幼敏悟过人,读书辄成诵。这篇文章主要讲述#星光计划2.0#HarmonyOS开发,从listContainer谈容器类控件的使用相关的知识,希望能为你提供帮助。
1.什么叫容器类控件容器类控件在生活中还是比较常见的,比如文件列表,图片轮播等等
2.容器类控件有什么特点容器类控件主要就是负责容纳真正的内容,在界面上一般没有自己真正的"
形象"
,属于内容后面的绿叶,在后面默默的撑起控件的光彩.
以listContainer的示意图:
文章图片
假设我们有一个下载列表,要做这样一个列表,有两种方法,一种就是硬编码,把东西一个一个写在layout上面,但那显然是最低级最无脑的做法,咱们程序员都自诩高智商人才,不能做那蠢事是不.
另一种高级的做法就是搞一个列表容器,把要显示的内容抽象成一个小的layout,然后按顺序排列出来塞到listContainer就行.
3.怎么学 3.1 准备好你的layout内容
首先是官方的教程:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-listcontainer-0000001060007847
这篇教程很基础,介绍了一个最基本的列表容器,但是也仅限基础,如果是app开发新手比如我这样的就很容易搞蒙,一眼看去不知所以,所以我觉得还是按我的方式去解释这个东西.
4.准备工作首先设计好你要展示的内容,比如下载列表,我们设计成左边放一张图片,右边分两个控件,一个Text,下方放一个进度条,大概就这意思:
文章图片
先把这个layout设计出来:
<
?xml version="1.0" encoding="utf-8"?>
<
DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:
ohos:
ohos:orientation="horizontal">
<
Image
ohos:id="$+id:movie_img"
ohos:
ohos:
ohos:layout_alignment="left"
ohos:image_src="https://www.songbingjia.com/android/$media:setting"
ohos:scale_mode="clip_center"
/>
<
DirectionalLayout
ohos:id="$+id:movie_info"
ohos:
ohos:
ohos:orientation="vertical"
>
<
Text
ohos:id="$+id:movie_name"
ohos:
ohos:
ohos:left_margin="3vp"
ohos:text_size="30fp"
ohos:text="亮剑-18"
/>
<
ProgressBar
ohos:id="$+id:progressbar"
ohos:progress_
ohos:
ohos:
ohos:max="100"
ohos:min="0"
ohos:progress="60"/>
<
/DirectionalLayout>
<
/DirectionalLayout>
预览窗口看见到是这样:
文章图片
3.2 准备listContainer
有了layout,还要有容器把他装起来,就跟果树长果子一样,有了果子,还得有树.
<
?xml version="1.0" encoding="utf-8"?>
<
DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:
ohos:
ohos:orientation="vertical">
<
Text
ohos:
ohos:
ohos:text="下载列表"
ohos:text_size="30vp"
ohos:top_margin="10vp"
ohos:text_alignment="center"
/>
<
ListContainer
ohos:id="$+id:download_list"
ohos:
ohos:
ohos:scrollbar_background_color="#d2a456"
>
<
/ListContainer>
<
/DirectionalLayout>
但是这东西没有界面,目前还没法预览,实在要预览的话是这个界面
文章图片
4.初始化在下载列表的abilitySlice的onStart里面假如初始化函数:
@Override
protected void onStart(Intent intent)
super.onStart(intent);
setUIContent(ResourceTable.Layout_movie_containerlist);
initDownloadListContainer();
private void initDownloadContainerList()
ListContainer listContainer=(ListContainer) findComponentById(ResourceTable.Id_download_list);
if(listContainer != null)
ArrayList<
downloadItem>
list=getData();
downloadItemProvider itemPro=new downloadItemProvider(list,this);
listContainer.setItemProvider(itemPro);
看第10行,首先咱们把listContainer获取到,为什么要获取到呢,因为接下来我们就要往里塞东西了.
那怎么塞呢,看第15行,我们往这个listContainer里面设置了一叫itemPro的东西,这里引入了一个Provider,这个provider负责帮我们提供数据,对于这个provider官方的文档有简单的几个接口介绍:
文章图片
其他的都还好懂,感觉最后一个有些费解,什么意思呢:
你那个listContainer嘛,里面肯定是有很多项,像一个数组一样,我们想拿到每一个列表项里面的图形控件,就得用这个接口,不然大家都长一样,你怎么知道你的数据结构对应哪个图形控件.
这里我们看到itemPro的创建需要一个list做参数,那在java里面就用ArrayList了,我们就来实现一下这个获取列表的接口:
private ArrayList<
downloadItem>
getData()
ArrayList<
downloadItem>
list=new ArrayList<
>
();
for (int i=0;
i<
8;
i++)downloadItem item = new downloadItem("亮剑-"+i+1);
DirectionalLayout layout = (DirectionalLayout) LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_movie_item,null,false);
item.setLayout(layout);
item.setProgress(i*10);
list.add(item);
return list;
这个很好理解了,就是创建一个list,然后把数据填充进去,这里的示例,我让每一个列表显示不一样的文字,然后再把每个进度条显示不一样的值,返回过去就行了.
这里面又涉及到一个东西,就是我们的downloadItem,这个item其实就是对应的我们那个下载信息展示的具体信息,就是java里面的一个类,先创造出一个结构类出来:
public class downloadItem private static final String TAG = imageScannerSlice.class.getSimpleName();
private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, TAG);
String name;
Image image;
int progress;
//[0-100]%DirectionalLayout layout;
public downloadItem(String name)
this.name = name;
public void downloadItem(String name, Image img)
this.name = name;
this.image = image;
public void setLayout(DirectionalLayout layout)
if(layout == null)
HiLog.error(LABEL_LOG,"setLayout is NULL");
return;
this.layout =layout;
Text text =(Text) layout.findComponentById(ResourceTable.Id_movie_name);
text.setText(name);
public void setProgress(int progress)
if(progress<
0) progress=0;
if (progress>
100) progress=100;
this.progress = progress;
if(layout == null)
return;
ProgressBar progressBar =(ProgressBar) layout.findComponentById(ResourceTable.Id_progressbar);
progressBar.setProgressValue(progress);
【#星光计划2.0#HarmonyOS开发,从listContainer谈容器类控件的使用】以看到,我们在这个结构里面做了一个setLayout的动作,这个就是为了把我们每个结构对应的图形控件对应起来,有了这东西,在Provider里面的getComponent接口里面就好填充数据了,整个provider长这样:
public class downloadItemProvider extends BaseItemProvider private List<
downloadItem>
list;
private AbilitySlice slice;
public downloadItemProvider(List<
downloadItem>
list, AbilitySlice slice)
this.list = list;
this.slice = slice;
@Override
public int getCount()
return this.list!=null ? this.list.size() : 0;
@Override
public Object getItem(int i)
if(this.list != null &
&
i>
0 &
&
i <
list.size())return this.list.get(i);
return null;
@Override
public long getItemId(int i) return i;
@Override
public Component getComponent(int i, Component component, ComponentContainer componentContainer) if(component != null)
return component;
downloadItem item = (downloadItem)this.getItem(i);
return item.layout;
可以看到我们的getComponent就是把我们的downloadItem找到,然后直接返回我们事先用setlayout接口传进去的layout控件.
5.效果展示把上面的代码片段进行整合,放进工程里面,最后的效果就是这样:
文章图片
到这里,我们的listContainer,列表容器控件就完成了,如果感觉没看懂的,可以先去看一下官方的教程:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-listcontainer-0000001060007847
然后再来看本教程,应该就能理清了.
6.pageSlider控件所谓的pageSlider能够实现一个大图轮播的效果,官方文档在这:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-pageslider-0000001091933258
效果在官方手册上也有
从编程逻辑上来说,跟listContainer的逻辑是一样的,首先准备好你的展示页面,
然后创建一个容器:pageSlide,再给pageSlider一个Provider用来提供数据,再初始化一下就好了,
如果读懂了上面listContainer的逻辑,这个pagesiler简直就太小儿科了,基于这样的逻辑,我们能很快把我们的下载列表改造成pagesilde形式:
相关的xml文件我就不贴了,参照官方代码就可以做到
public class downloadItemPageProvider extends PageSliderProvider
//数据实体类
//public static class DataItem
//String mText;
//public DataItem(String txt)
//mText = txt;
//
//
// 数据源,每个页面对应list中的一项
private List<
downloadItem>
list;
private Context mContext;
public downloadItemPageProvider(List<
downloadItem>
list, Context context)
this.list = list;
this.mContext = context;
@Override
public int getCount()
return list.size();
@Override
public Object createPageInContainer(ComponentContainer componentContainer, int i) final downloadItem item = list.get(i);
//DirectionalLayout layout =new DirectionalLayout(mContext);
//(DirectionalLayout) componentContainer.findComponentById(ResourceTable.Id_home_info);
DirectionalLayout layout =(DirectionalLayout) LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_home_info,null,false);
componentContainer.addComponent(layout);
item.setLayout(layout);
return layout;
@Override
public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o)
componentContainer.removeComponent((Component) o);
@Override
public boolean isPageMatchToObject(Component component, Object o)
//可添加具体处理逻辑
//...
return true;
这个pageSlid的Provider跟List的Provider大体逻辑差不多的,只是稍稍有些不同,就是这个里面需要实现createPageInContainer,而不是list的Provider里面的getComponent接口,但是仔细观察我里面的代码,跟之前那个如出一辙,
然后改造一下初始化那里:
private void initPageSlide(String account)
pageSlider = (PageSlider) findComponentById(ResourceTable.Id_page_slider);
pageSlider.setProvider(new downloadItemPageProvider(getData(), this));
这样就能轻松的做出一个左右滑屏的页面滑动器
文章图片
7.总结个人感觉比较自豪的一处是那个数据结构跟图形控件绑定的逻辑,比官方的好用
其实总结下来,做容器类的空间需要的流程是:
文章图片
理解了这个套路.你就能做出想要的效果
其实还可以把pageSilde和listContainer结合起来使用做出更复杂好玩的界面效果,期待你的反馈
想了解更多关于鸿蒙的内容,请访问:
51CTO和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com/#bkwz
::: hljs-center
文章图片
:::
推荐阅读
- #yyds干货盘点#老王读Spring AOP-1Pointcut如何匹配到 join point
- Java编程后端开发小书架!毛遂自荐
- #yyds干货盘点# linux iscsi 简单实现windows文件互通和实现多路径访问,并实现负载均衡高可用超详细配置方法和原理的个人理解
- Bitlocker磁盘加密策略Without TPM---Intune终结点管理
- JVM调优指南-工具篇(jps)
- Win10 LTSC封装教程
- 学习Java必备的基础知识打卡12.23,要想学好必须扎实基本功(?建议收藏)#yyds干货盘点#
- # yyds干货盘点 # 手把手教你如何新建scrapy爬虫框架的第一个项目(上)
- Spring认证中国教育管理中心-Apache Geode 的 Spring 数据教程五