元素之歌鸿蒙怎么合成,鸿蒙「3.4 熟知的列表」闯荡HAP之单-列表和组装列表

9c1f860de3f325935554cf451b987121.png

在一个文件夹里会罗列出很多个子文件夹或者文件,包含文件名、文件大小、文件修改日期、文件类型等;

在一个内容网站里会罗列出很多条内容,或许还要翻页,包含文章标题、文章作者、发表时间、浏览量等;

在一个图册网站,里面会罗列出很多图集或者图片,包含图集名称、图集作者等;

在一个音乐播放器的具体某类歌曲中,会罗列出很多歌曲,包含歌名、作者、所属歌集、时长等;

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

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

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

一、单一的列表

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

xmlns:ohos="http://schemas.huawei.com/res/ohos"

ohos:height="match_parent"

ohos:width="match_parent"

ohos:orientation="vertical">

ohos:id="$+id:fruit_list"

ohos:height="match_parent"

ohos:width="match_parent"

ohos:layout_alignment="horizontal_center"/>

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

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">

ohos:id="$+id:element_index"

ohos:height="match_content"

ohos:width="match_content"

ohos:padding="4vp"

ohos:text_size="30fp"

ohos:layout_alignment="center"/>

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

List 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;

publicclass FruitElementProvider extends BaseItemProvider {

private List list;

private AbilitySlice slice;

publicFruitElementProvider(List fruits, AbilitySlice slice) {

this.list = fruits;

this.slice = slice;

}

@Override

publicintgetCount() {

returnlist.size();

}

@Override

publicObject getItem(inti) {

returnlist.get(i);

}

@Override

publiclong getItemId(inti) {

returni;

}

@Override

publicComponent getComponent(inti, 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);

returncpt;

}

}

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

ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_fruit_list);

List 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、运行查看效果。

0a1507580a5be626ff867ab3103857f7.png

二、组合复杂的列表

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()) {

returnresponse.body().string();

}

}

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

1b114fe1c788603cce930d7999550e92.png

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

publicclass 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组件的子布局,代码如下:

xmlns:ohos="http://schemas.huawei.com/res/ohos"

ohos:height="match_content"

ohos:width="match_parent"

ohos:bottom_margin="4vp"

ohos:orientation="vertical">

ohos:height="match_parent"

ohos:width="match_parent"

ohos:background_element="$graphic:background_element"

ohos:orientation="horizontal">

ohos:id="$+id:news_imgsrc"

ohos:image_src="$media:icon"

ohos:height="100vp"

ohos:width="100vp"/>

ohos:height="match_parent"

ohos:width="match_parent">

ohos:id="$+id:news_title"

ohos:height="match_parent"

ohos:width="match_parent"

ohos:weight="1"

ohos:text="我是标题"

ohos:text_size="20fp"/>

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"/>

ohos:height="match_parent"

ohos:width="match_parent"

ohos:weight="1">

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"/>

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"/>

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

@Override

publicComponent getComponent(inti, 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());

returncpt;

}

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

/**

* 复杂数据结构

*/

private void initNewsListContainer() {

//在子线程中获取数据

new Thread(new Runnable() {

@Override

publicvoid run() {

try {

String response = MainAbilitySlice.this.run("https://api.tianapi.com/bulletin/index?key=您自己的KEY");

System.out.println(response);

JSONObject jsonObject = JSONObject.parseObject(response);

intcode =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 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();

}

02533d3960f86188afbeef0fd61f8b45.png

我的HarmonyOS GitHub库

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

【编辑推荐】

【责任编辑:jianghua TEL:(010)68476606】

点赞 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值