当前位置:首页 > 域名

鸿蒙「3.4 熟知的列表」闯荡HAP之单-列表和组装列表

 

想了解更多内容,鸿蒙和组请访问:

和华为官方合作共建的熟知鸿蒙技术社区

https://harmonyos.51cto.com/#zz

在一个文件夹里会罗列出很多个子文件夹或者文件,包含文件名、列荡文件大小、表闯表文件修改日期、单装列文件类型等; 在一个内容网站里会罗列出很多条内容,列表或许还要翻页,鸿蒙和组包含文章标题、熟知文章作者、列荡发表时间、表闯表浏览量等; 在一个图册网站,单装列里面会罗列出很多图集或者图片,列表包含图集名称、鸿蒙和组图集作者等; 在一个音乐播放器的熟知具体某类歌曲中,会罗列出很多歌曲,列荡包含歌名、作者、所属歌集、时长等;

还有很多想类似的情况,这里就不一一列举了。通过上面四个场景,我们可以发现一个共同的特点,它们都有很多条数据,每个场景中数据的属性是相同的。这就让我想起了在学习Java 的数组时,对于一维数组,亿华云其元素的类型是相同的,你不可能定义了一个整形的数组,向里面添加了字符串类型的元素,这是不行的。假如我们需要做一个新闻类的展示界面,那么我们的数据中,每个元素中的属性必须是一样的。比如我们的元素属性包含标题、作者、内容摘要、封面图、发布时间、浏览记录、点赞量、评论量,但是在这个列表中存在一个特殊的元素,它的属性为歌曲名称、源码库作者、歌集、时长,那么我们在展示这个数据集的时候,会出现什么问题呢(这里不做详细说明了,也许你已经知道答案是什么了)?

对于ListContainer组件的理论不在这里做赘述了,官文已经说得很明白了,本节将结合OkHttp插件,来使用ListContainer组件做一个简单的新闻展示Demo。

在开始复杂的列表展示页之前,我们先来做一个简单的列表展示,在学习Android的时候,列表有个展示水果的示例,我将在HarmonyOS智慧屏上实现这个小示例。

一、单一的列表

1、在layout目录下新建fruit_layout.xml文件,并创建ListContainer组件,代码如下:

<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout     xmlns:ohos="http://schemas.huawei.com/res/ohos"     ohos:height="match_parent"     ohos:width="match_parent"     ohos:orientation="vertical">     <ListContainer         ohos:id="$+id:fruit_list"         ohos:height="match_parent"         ohos:width="match_parent"         ohos:layout_alignment="horizontal_center"/> </DirectionalLayout> 

 2、接着在layout目录新建element_layout.xml文件,作为ListContainer组件的子布局,代码如下: 

<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout     xmlns:ohos="http://schemas.huawei.com/res/ohos"     ohos:height="match_content"     ohos:width="match_parent"     ohos:background_element="$graphic:background_element"     ohos:bottom_margin="4vp"     ohos:orientation="vertical">     <Text         ohos:id="$+id:element_index"         ohos:height="match_content"         ohos:width="match_content"         ohos:padding="4vp"         ohos:text_size="30fp"         ohos:layout_alignment="center"/> </DirectionalLayout> 

 3、组建一个类型为String的云服务器List列表,最终呈现在UI界面上。

List<String> fruits = new ArrayList<>();    fruits.add("苹果");    fruits.add("橘子");    fruits.add("橙子");    fruits.add("香蕉");    fruits.add("梨");    fruits.add("桃子");    fruits.add("苹果梨");    fruits.add("香蕉梨");    fruits.add("冬桃");    fruits.add("红葡萄");    fruits.add("紫葡萄");    fruits.add("黑葡萄"); 

 4、ListContainer组件的每一行元素可以是不相同的数据,因此需要适配不同的数据结构,使其能够添加到ListContainer组件中,并以列表的形式呈现在UI界面上。ListContainer组件提供了setItemProvider​(BaseItemProvider itemProvider)方法,用于设置要显示的ListContainer组件对象。创建FruitElementProvider类,并继承BaseItemProvider,重写其中的方法。

package com.ming.harmonyos.newsapp.domain;  import com.ming.harmonyos.newsapp.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.agp.components.*;  import java.util.List;  public class FruitElementProvider extends BaseItemProvider {       private List<String> list;      private AbilitySlice slice;      public FruitElementProvider(List<String> fruits, AbilitySlice slice) {          this.list = fruits;         this.slice = slice;     }      @Override     public int getCount() {          return list.size();     }      @Override     public Object getItem(int i) {          return list.get(i);     }      @Override     public long getItemId(int i) {          return i;     }      @Override     public Component getComponent(int i, Component component, ComponentContainer componentContainer) {          Component cpt = component;         if (cpt == null) {              cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_element_layout, null, false);         }         String fruit = list.get(i);         Text text = (Text) cpt.findComponentById(ResourceTable.Id_element_index);         text.setText(fruit);         return cpt;     } } 

 5、在MainAbility中适配ListContainer的数据结构,并添加点击事件。

ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_fruit_list);        List<String> fruits = new ArrayList<>();        fruits.add("苹果");        fruits.add("橘子");        fruits.add("橙子");        fruits.add("香蕉");        fruits.add("梨");        fruits.add("桃子");        fruits.add("苹果梨");        fruits.add("香蕉梨");        fruits.add("冬桃");        fruits.add("红葡萄");        fruits.add("紫葡萄");        fruits.add("黑葡萄");        FruitElementProvider fruitElementProvider = new FruitElementProvider(fruits, this);        listContainer.setItemProvider(fruitElementProvider);        listContainer.setItemClickedListener((listContainer1, component, position, id) -> {             String item = (String) listContainer1.getItemProvider().getItem(position);            new ToastDialog(getContext())                    .setText("点击了:" + item)                    // Toast显示在界面中间                    .setAlignment(LayoutAlignment.CENTER)                    .show();        }); 

 6、运行查看效果。

二、组合复杂的列表

1、和单一列表不同之处在于元素的显示和元素的属性。单一列表中我使用了一个List,复杂的列表中,我将根据请求API接口返回的数据类型进行数据结构的组装。在这之前我先要说说OkHttp如何引入,以及需要授予那些权限。

1)首先我们在build.gradle中引入OkHttp(本节并不是对OkHttp做详细讲解,这里只是简单的使用)的版本,并点击窗口上的Sync Now进行同步下载。

implementation("com.squareup.okhttp3:okhttp:4.9.0") 

2)在config.json中配置INTENT权限。

"reqPermissions": [       {          "name": "ohos.permission.INTERNET",         "usedScene": {            "ability": [             "com.ming.harmonyos.newsapp.MainAbility"           ],           "when": "always"         }       }     ] 

 3)在MainAbilitySlice中实例化OkHttpClient对象,并封装它的GET调用方法。

private OkHttpClient client = new OkHttpClient();     private String run(String url) throws IOException {         Request request = new Request.Builder()                .url(url)                .build();         try (Response response = client.newCall(request).execute()) {             return response.body().string();        }    } 

 2、做好上面的准备之后,我使用天行数据的每日简报API接口。先看一下调用接口返回的参数:

3、我们根据返回的参数来构建我们的列表元素类。

public class News {      //新闻标题     private String title;     //简报内容     private String digest;     //简报封面     private String imgsrc;     //简报链接     private String url;     //简报来源     private String source;     //新闻时间     private String mtime;     //getter & setter } 

 4、在layout目录新建news_element_layout.xml文件,作为ListContainer组件的子布局,代码如下:

<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout     xmlns:ohos="http://schemas.huawei.com/res/ohos"     ohos:height="match_content"     ohos:width="match_parent"     ohos:bottom_margin="4vp"     ohos:orientation="vertical">      <DirectionalLayout         ohos:height="match_parent"         ohos:width="match_parent"         ohos:background_element="$graphic:background_element"         ohos:orientation="horizontal">         <Image             ohos:id="$+id:news_imgsrc"             ohos:image_src="$media:icon"             ohos:height="100vp"             ohos:width="100vp"/>         <DirectionalLayout             ohos:height="match_parent"             ohos:width="match_parent">             <Text                 ohos:id="$+id:news_title"                 ohos:height="match_parent"                 ohos:width="match_parent"                 ohos:weight="1"                 ohos:text="我是标题"                 ohos:text_size="20fp"/>             <Text                 ohos:id="$+id:news_remark"                 ohos:height="match_parent"                 ohos:width="match_parent"                 ohos:weight="1"                 ohos:text="我是摘要"                 ohos:text_size="14fp"                 ohos:multiple_lines="true"                 ohos:max_text_lines="2"                 ohos:text_color="#888888"/>             <DependentLayout                 ohos:height="match_parent"                 ohos:width="match_parent"                 ohos:weight="1">                 <Text                     ohos:id="$+id:news_source"                     ohos:height="match_content"                     ohos:width="match_content"                     ohos:text="来源"                     ohos:text_size="12fp"                     ohos:text_color="#CCCCCC"                     ohos:align_parent_left="true"/>                 <Text                     ohos:id="$+id:news_time"                     ohos:height="match_content"                     ohos:width="match_content"                     ohos:text="时间"                     ohos:text_size="12fp"                     ohos:text_color="#CCCCCC"                     ohos:right_padding="20vp"                     ohos:align_parent_right="true"/>             </DependentLayout>         </DirectionalLayout>     </DirectionalLayout> </DirectionalLayout> 

 5、创建NewsItemProvider类,并继承BaseItemProvider,重写其中的方法。

@Override   public Component getComponent(int i, Component component, ComponentContainer componentContainer) {        Component cpt = component;       if (cpt == null) {            cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_news_element_layout, null, false);       }       News news = list.get(i);       //封面图       Image image = (Image) cpt.findComponentById(ResourceTable.Id_news_imgsrc);              //标题       Text title = (Text) cpt.findComponentById(ResourceTable.Id_news_title);       title.setText(news.getTitle());       //摘要       Text remark = (Text) cpt.findComponentById(ResourceTable.Id_news_remark);       remark.setText(news.getDigest());       //来源       Text source = (Text) cpt.findComponentById(ResourceTable.Id_news_source);       source.setText(news.getSource());       //日期       Text time = (Text) cpt.findComponentById(ResourceTable.Id_news_time);       time.setText(news.getMtime());       return cpt;   } 

 6、在MainAbility中使用OkHttp获取数据并适配ListContainer的数据结构,最后查看运行效果。

/**     * 复杂数据结构     */    private void initNewsListContainer() {         //在子线程中获取数据        new Thread(new Runnable() {             @Override            public void run() {                 try {                     String response = MainAbilitySlice.this.run("https://api.tianapi.com/bulletin/index?key=您自己的KEY");                    System.out.println(response);                    JSONObject jsonObject = JSONObject.parseObject(response);                    int code = Integer.valueOf(String.valueOf(jsonObject.get("code")));                    String message = String.valueOf(jsonObject.get("msg"));                    String data = String.valueOf(jsonObject.get("newslist"));                    if (code == 200) {                         List<News> list = JSONArray.parseArray(data, News.class);                        ListContainer news = (ListContainer) findComponentById(ResourceTable.Id_news_list);                        NewsItemProvider nip = new NewsItemProvider(list, MainAbilitySlice.this);                        news.setItemProvider(nip);                    } else {                         new ToastDialog(getContext())                                .setText("抛出异常信息: " + message)                                .setAlignment(LayoutAlignment.CENTER)                                .show();                    }                } catch (Exception e) {                     e.printStackTrace();                }            }        }).start();    } 

 

我的HarmonyOS GitHub库

©著作权归作者和HarmonyOS技术社区共同所有,如需转载,请注明出处,否则将追究法律责任

想了解更多内容,请访问:

和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

-->

分享到:

滇ICP备2023006006号-16