更多信息请访问:与华为共建Harmonyos技术社区https://harmonyos.51cto.com/#zz一个文件夹中,很多子文件夹或文件会列出,包括文件名、文件大小、文件修改日期、文件类型等;在内容网站中,会列出许多内容项,并且可能需要翻页。包括文章标题、文章作者、发表时间、浏览量等;在相册网站上,会列出很多图集或图片,包括图集名称、图集作者等;在某个音乐播放器的特定类别的歌曲中,会列出很多首歌曲,包括歌名、作者、歌本、时长等;类似的情况还有很多,这里就不一一列举了。通过以上四种场景,我们可以发现一个共同的特点,它们都有很多条数据,并且每个场景中数据的属性都是相同的。这让我想起了我在学习Java数组的时候,对于一维数组来说,元素的类型是一样的,你不能定义一个整型数组,然后往里面添加字符串类型的元素,这是不行的。如果我们需要做一个新闻展示界面,那么在我们的数据中,每个元素中的属性必须是相同的。比如我们的元素属性包括标题、作者、内容概要、封面图、发布时间、浏览历史、点赞、评论,但是这个列表中有一个特殊的元素,它的属性是歌名、作者、歌本、时长,然后当我们展示这个数据集的时候,会出现什么问题(这里就不细说了,也许你已经知道答案是什么了)?ListContainer组件的原理我这里就不重复了,官方文档已经说的很清楚了,本节将结合OkHttp插件使用ListContainer组件做一个简单的新闻展示demo。在开始复杂的列表展示页面之前,我们先来做一个简单的列表展示。学习Android的时候,列表里有个展示水果的例子。我将在HarmonyOS智慧屏上实现这个小例子。一、单列表1、在layout目录下新建一个fruit_layout.xml文件,并创建一个ListContainer组件。代码如下:2、然后在layout目录下新建element_layout.xml文件,作为ListContainer组件的子布局,代码如下:3.创建一个类型String的列表最终呈现在UI界面上Listfruits=newArrayList<>();fruits.add("apple");fruits.add("orange");fruits.add("orange");fruits.add("香蕉");fruits.add("梨");fruits.add("桃子");fruits.add("苹果梨");fruits.add("香蕉梨");fruits.add("冬桃");fruits.add("红葡萄");fruits.add("紫葡萄");fruits.add("黑葡萄");4.ListContainer组件每一行的元素都可以不同的数据,需要适配不同的数据结构,才能添加到ListContainer组件中,以列表的形式呈现在UI界面上。ListContainer组件提供了setItemProvider(BaseItemProvideritemProvider)方法来设置ListContainer要显示的Component对象。创建FruitElementProvider类,继承自BaseItemProvider,并重写其中的方法。packagecom.ming.harmonyos.newsapp.domain;importcom.ming.harmonyos.newsapp.ResourceTable;importohos.aafwk.ability.AbilitySlice;importohos.agp.components.*;importjava.util.List;publicclassFruitElementProviderextendsBaseItemProvider{privateListlist;privateAbilitySliceslice;publicFruitElementProvider(Listfruits,AbilitySliceslice){this.list=fruits;this.slice=slice;}@OverridepublicintgetCount(){returnlist.size();}@OverridepublicObjectgetItem(inti){returnlist.get(i);}@OverridepubliclonggetItemId(inti){returni;}@OverridepublicComponentgetComponent(inti,Componentcomponent,ComponentContainercomponentContainer){Componentcpt=component;if(cpt==null){cpt=LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_element_layout,null,false);}Stringfruit=list.get(i);Texttext=(Text)cpt.findComponentById(ResourceTable.Id_element_index);text.setText(fruit);returncpt;}}5、在MainAbility中适配ListContainer的数据结构,并添加点击事件。ListContainerlistContainer=(ListContainer)findComponentById(ResourceTable.Id_fruit_list);Listfruits=newArrayList<>();fruits.add("apple");fruits.add("orange");fruits.add("orange");fruits.add("香蕉");fruits.add("梨");fruits.add("桃子");fruits.add("苹果梨");fruits.add("香蕉梨");水果。add("冬桃");fruits.add("红葡萄");fruits.add("紫葡萄");fruits.add("黑葡萄");FruitElementProviderfruitElementProvider=newFruitElementProvider(fruits,this);listContainer.setItemProvider(水果元素提供者);listContainer.setItemClickedListener((listContainer1,component,position,id)->{Stringitem=(String)listContainer1.getItemProvider().getItem(position);newToastDialog(getContext()).setText("clicked:"+item)//Toast显示在界面中间setAlignment(LayoutAlignment.CENTER).show();});6.运行查看效果。二、组合复杂列表1、与单个列表的区别在于元素的显示和元素的属性。在单个列表中,我使用了一个列表。在复杂列表中,我会根据请求API接口返回的数据类型来组装数据结构。在此之前先说一下OkHttp是如何引入的,需要授予哪些权限。1)首先我们在build.gradle中引入OkHttp的版本(本节不对OkHttp进行详细讲解,这里只是简单的使用),在窗口点击SyncNow进行同步下载。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调用方法。privateOkHttpClientclient=newOkHttpClient();privateStringrun(Stringurl)throwsIOException{Requestrequest=newRequest.Builder().url(url).build();try(Responseresponse=client.newCall(request).execute()){returnresponse.body().string();}}2、做好以上准备后,我使用天行数据的每日简报API接口。先看调用接口返回的参数:3.我们根据返回的参数构建我们的列表元素类。publicclassNews{//新闻标题privateStringtitle;//新闻内容privateStringdigest;//新闻封面privateStringimgsrc;//新闻链接privateStringurl;//新闻来源privateStringsource;//新闻时间privateStringmtime;//getter&setter}4.在news_element_layout中新建news_element_layout布局目录。xml文件,作为ListContainer组件的子布局,代码如下:5.创建一个NewsItemProvider类,继承自BaseItemProvider,重写里面的方法@OverridepublicComponentgetComponent(inti,Componentcomponent,ComponentContainercomponentContainer){Componentcpt=component;if(cpt==null){cpt=LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_news_element_layout,null,false);}Newsnews=list.get(i);//封面图片Imageimage=(Image)cpt.findComponentById(ResourceTable.Id_news_imgsrc);//标题Texttitle=(Text)cpt.findComponentById(ResourceTable.Id_news_title);title.setText(news.getTitle());//SummaryTextremark=(Text)cpt.findComponentById(ResourceTable.Id_news_remark);remark.setText(news.getDigest());//SourceTextsource=(Text)cpt.findComponentById(ResourceTable.Id_news_source);source.setText(news.getSource)());//DateTexttime=(Text)cpt.findComponentById(ResourceTable.Id_news_time);time.setText(news.getMtime());returncpt;}6.使用OkHttp获取MainAbility中的数据,适配ListContainer的数据结构,最后检查运行效果。/***复杂数据结构*/privatevoidinitNewsListContainer(){//在子线程中获取数据newThread(newRunnable(){@Overridepublicvoidrun(){try{Stringresponse=MainAbilitySlice.this.run("https://api.tianapi.com/bulletin/index?key=你自己的KEY");System.out.println(response);JSONObjectjsonObject=JSONObject.parseObject(response);intcode=Integer.valueOf(String.valueOf(jsonObject.get("代码")));Stringmessage=String.valueOf(jsonObject.get("msg"));Stringdata=String.valueOf(jsonObject.get("newslist"));if(code==200){Listlist=JSONArray.parseArray(data,News.class);ListContainernews=(ListContainer)findComponentById(ResourceTable.Id_news_list);NewsItemProvidernip=newNewsItemProvider(list,MainAbilitySlice.this);news.setItemProvider(nip);}else{newToastDialog(getContext()).setText("Throwinganexceptionmessage:"+message).setAlignment(LayoutAlignment.CENTER).show();}}catch(Exceptione){e.printStackTrace();}}}).start();}I的HarmonyOSGitHubrepository?版权归作者所有鸿蒙技术社区共同拥有,如需转载请注明出处,否则将追究法律责任更多信息请访问:与华为官方共建的鸿蒙技术社区https://harmonyos.51cto.com/#zz