赞
踩
本文将专门花一篇来讲述ListContainer和PageSlider,ListContainer主要是参考官方例子,PageSlider在原有官方例子上进行了一些升级改造。原有例子添加固定的文字,通过改造动态读取本地json内容和本地图片资源。
Java UI组件中有些需要动态绑定数据的组件,因为系统不了解你的样式(布局)和行为(方法),这就必须要自己按着规则定义,这就导致组件使用为略显复杂,接下来就只讲一下这些稍微复杂的组件。
1、ListContainer实现思路分析
ListContainer列表容器,用来呈现多行连续的同类数据;导致ListContainer稍嫌复杂有两个原因:
1)列表中每项布局不确定,需要自定义布局(比如新闻每个列表项可能只有标题,也可能有标题、简介、图片,这会导致每行布局不一样)
2)内容不确定,动态绑定(新闻条数不确定、内容动态加载)
以上的不确定导致了每个布局需要自己定义,每个数据类型需要自己定义;
2、ListContainer实现步骤
1)定义ListContainer:layout下创建ListContainer组件
2)定义每项布局:layout下创建ListContainer的内容,即子布局,如果是带标题、简介、图片的新闻列表,就定义两个text和一个image。
3)定义数据实体类:每一条列表的具体组成java类
4)定义每条列表项的属性:通过实现BaseItemProvider类;因为每项列表内容不确定,通过重写getComponent方法,返回每项布局内容(第二步中的layerout是自定义且空的,这里定义布局和数据的组合方法)
5)组装ListContainer:通过BaseItemProvider的实现类将数据和ListContainer组合起来;
6)注册其他行为:比如定义点击事件、定义更新数据;
完整代码太长,结合上述步骤贴出核心代码,上部分布局类代码,下部分java类代码:
- //第一步创建layerout下ListContainer布局页面
- <ListContainer
- ohos:id="$+id:list_container"
- ohos:height="200vp"
- ohos:width="350vp"
- ohos:layout_alignment="horizontal_center"/>
- //第二步创建子布局,这里用两个字段name和address来展示
- <Text
- ohos:id="$+id:item_index"
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:padding="4vp"
- ohos:text="Item0"
- ohos:text_size="20fp"
- ohos:layout_alignment="center"/>
- <Text
- ohos:id="$+id:item_index1"
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:padding="4vp"
- ohos:text="Item0"
- ohos:text_size="20fp"
- ohos:layout_alignment="left"/>
- //第三步,创建ItemBean实体类
- public class ItemBean {
- private String name;
- private String address;
- public ItemBean(String name,String address) {
- this.name = name;
- this.address=address;
- }
- //属性get、set方法省略...
- }
-
- //第四步,实现BaseItemProvider类,必须实现以下override方法,这样系统就可以根据这些方法对listContainer内容进行组装,并提供一些行为(比如查询长度、返回ID)
- public class ItemProvider extends BaseItemProvider {
- private List<ItemBean> list;
- private AbilitySlice abilitySlice;
- public ItemProvider(List<ItemBean> list, AbilitySlice abilitySlice) {
- this.list = list;
- this.abilitySlice = abilitySlice;
- }
- @Override
- public int getCount() {
- return list.size();
- }
- @Override
- public Object getItem(int i) {
- if(list!=null&&list.size()>0){
- return list.get(i);
- }
- return null;
- }
- @Override
- public long getItemId(int i) {
- return i;
- }
-
- @Override
- public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
- Component temp;
- if(component==null){
- temp=LayoutScatter.getInstance(abilitySlice).parse(ResourceTable.Layout_list_container_item,null,false);
- }else{
- temp=component;
- }
- ItemBean itemBean= list.get(i);
- Text text1=temp.findComponentById(ResourceTable.Id_item_index);
- text1.setText(itemBean.getName());
- Text text2 =temp.findComponentById(ResourceTable.Id_item_index1);
- text2.setText(itemBean.getAddress());
- return temp;
- }
- }
-
- //第五步,在PageSlice里面根据ItemProvider组装ListContainer,构造一个长度20的列表
- private void initListContainer() {
- ListContainer listCon=findComponentById(ResourceTable.Id_list_container);
- List<ItemBean> list=getData();
- ItemProvider itemProvider=new ItemProvider(list,this);
- listCon.setItemProvider(itemProvider);
- }
- private List<ItemBean> getData(){
- List<ItemBean> list=new ArrayList<>();
- for(int i=0;i<20;i++){
- ItemBean itembean=new ItemBean("item"+i,"address"+i);
- list.add(itembean);
- }
- return list;
- }
- //第六步,定义点击事件
- listCon.setItemClickedListener((container, component, position, id)->{
- ItemBean itemBean=(ItemBean)container.getItemProvider().getItem(position);
- new ToastDialog(this)
- .setText("你点击了"+itemBean.getName()+"__"+itemBean.getAddress())
- .setAlignment(LayoutAlignment.HORIZONTAL_CENTER).show();
- });
以上代码实现效果:
PageSlider可以通过滚动实现页面间内容切换,每个页面样式内容当然不确定;实现思路和ListContainer一模一样,这里就直接贴出核心代码。
为了练习,里面添加通过代码创建Text(内容)、image、Text(通过事件获取页码);
- //第一步创建PageSlider
- <PageSlider
- ohos:id="$+id:page_slider"
- ohos:height="300vp"
- ohos:width="300vp"
- ohos:layout_alignment="horizontal_center"/>
- <!--页面导航,前期先不用
- <PageSliderIndicator
- ohos:id="$+id:indicator"
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:padding="8vp"
- ohos:layout_alignment="horizontal_center"
- ohos:top_margin="16vp"
- ohos:background_element="#55FFC0CB"/>
- -->
-
- //第二步创建页面的子布局
- <Text
- ohos:id="$+id:item_title"
- ohos:height="match_content"
- ohos:width="match_content"
- ohos:layout_alignment="top|center"
- ohos:padding="4vp"
- ohos:text="Item0"
- ohos:text_size="20fp"/>
- <Image
- ohos:id="$+id:imageComponent"
- ohos:height="200vp"
- ohos:width="match_parent"
-
- />
- <Text
- ohos:id="$+id:item_page_num"
- ohos:height="40vp"
- ohos:width="80vp"
- ohos:layout_alignment="bottom|center"
- ohos:padding="4vp"
- ohos:text="Item0"
- ohos:text_size="20fp"
- />
- //第三步,布局数据内容的实体类
- public class ItemPageSlider {
- private String title;
- private String imageUrl;
- private String pageNum;
-
- public ItemPageSlider(String title, String imageUrl, String pageNum) {
- this.title = title;
- this.imageUrl = imageUrl;
- this.pageNum = pageNum;
- }
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- public String getPageNum() {
- return pageNum;
- }
- public void setPageNum(String pageNum) {
- this.pageNum = pageNum;
- }
- public String getImageUrl() {
- return imageUrl;
- }
- public void setImageUrl(String imageUrl) {
- this.imageUrl = imageUrl;
- }
- }
-
- //第四步,构建数据提供者
- public class ItemPageSliderProvider extends PageSliderProvider {
- private List<ItemPageSlider> list;
- private Context context;
- public ItemPageSliderProvider(List<ItemPageSlider> list, Context context) {
- this.list = list;
- this.context = context;
- }
- @Override
- public int getCount() {
- return list.size();
- }
- //组装也面内容
- @Override
- public Object createPageInContainer(ComponentContainer componentContainer, int i) {
- Component component = LayoutScatter.getInstance(this.context).parse(ResourceTable.Layout_page_slider_item, null, false);
- Text title = component.findComponentById(ResourceTable.Id_item_title);
- title.setText(list.get(i).getTitle());
- Text pageNum = component.findComponentById(ResourceTable.Id_item_page_num);
- pageNum.setText(list.get(i).getPageNum());
- Image image = component.findComponentById(ResourceTable.Id_imageComponent);
- image.setPixelMap(CommonUtils.getPixelMapFromPath(context, list.get(i).getImageUrl()));
- componentContainer.addComponent(component);
- return component;
- }
- //注意必须要实现销毁类,不然内容不断添加,并不会移除
- @Override
- public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
- componentContainer.removeComponent((Component)o);
-
- }
- @Override
- public boolean isPageMatchToObject(Component component, Object o) {
- return false;
- }
- }
-
- //第五步,构建数据提供者
- private void initPageSlider() {
- PageSlider pageSlider = findComponentById(ResourceTable.Id_page_slider);
- ItemPageSliderProvider itemPageSliderProvider=new ItemPageSliderProvider(getData(),this);
- pageSlider.setProvider(itemPageSliderProvider);
- //监听页面变化
- pageSlider.addPageChangedListener(new PageSlider.PageChangedListener() {
- @Override
- public void onPageSliding(int i, float v, int i1) {
- //....
- }
-
- @Override
- public void onPageSlideStateChanged(int i) {
- //....
- }
-
- @Override
- public void onPageChosen(int i) {
- new ToastDialog(getContext()).setText("当前页面索引:"+i++).show();
- }
- });
- //添加页面导航,启用前面的xml布局中PageSliderIndicator,配合此段代码即可实现页面导航
- PageSliderIndicator indicator = (PageSliderIndicator)findComponentById(ResourceTable.Id_indicator);
- ShapeElement normalElement = new ShapeElement();
- normalElement.setRgbColor(RgbColor.fromArgbInt(0xADD8E6));
- normalElement.setAlpha(168);
- normalElement.setShape(ShapeElement.OVAL);
- normalElement.setBounds(0, 0, 32, 32);
- ShapeElement selectedElement = new ShapeElement();
- selectedElement.setRgbColor(RgbColor.fromArgbInt(0x00BFFF));
- selectedElement.setAlpha(168);
- selectedElement.setShape(ShapeElement.OVAL);
- selectedElement.setBounds(0, 0, 48, 48);
- indicator.setItemElement(normalElement, selectedElement);
- indicator.setItemOffset(60);
- indicator.setPageSlider(pageSlider);
- }
辅助类,用于读取页面内容(用本地文件json定义)、图片 (显示图片资源)
- public class CommonUtils {
- private static final String TAG = "CommonUtils";
- //读取资源图片
- public static PixelMap getPixelMapFromPath(Context context, String path) {
- InputStream inputStream = null;
- try {
- inputStream = context.getResourceManager().getRawFileEntry(path).openRawFile();
- ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
- sourceOptions.formatHint = "image/jpg";
- ImageSource imageSource = ImageSource.create(inputStream, sourceOptions);
- ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
- decodingOptions.desiredSize = new Size(0, 0);
- decodingOptions.desiredRegion = new Rect(0, 0, 0, 0);
- decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
- return imageSource.createPixelmap(decodingOptions);
- } catch (IOException e) {
- LogUtil.error(TAG, e.getMessage());
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException ex) {
- LogUtil.error(TAG, ex.getMessage());
- }
- }
- return null;
- }
-
- //读取资源文件json内容
- public static String getStringFromPath(Context context, String path) {
- try {
- Resource dataResource = context.getResourceManager().getRawFileEntry(path).openRawFile();
- byte[] buffers = new byte[dataResource.available()];
- if (dataResource.read(buffers) != -1) {
- return new String(buffers, StandardCharsets.UTF_8);
- }
- } catch (IOException ex) {
- LogUtil.error(TAG, ex.getMessage());
- }
- return Optional.of(path).toString();
- }
-
- }
- [
- {
- "title": "向日葵",
- "imageUrl": "entry/resources/base/media/xiangrikui.jpg",
- "pageNum": "1"
- },
- {
- "title": "海滩",
- "imageUrl": "entry/resources/base/media/haitan.jpg",
- "pageNum": "2"
- },
- {
- "title": "萧山城市",
- "imageUrl": "entry/resources/base/media/xiaoshan.jpg",
- "pageNum": "3"
- },
- {
- "title": "郁金香",
- "imageUrl": "entry/resources/base/media/yujinxiang.jpg",
- "pageNum": ""
- },
- {
- "title": "鸽子",
- "imageUrl": "entry/resources/base/media/gezi.jpg",
- "pageNum": ""
- }
- ]
预期效果:
本文因为涉及到动态读取图片和内容稍微嫌的复杂,虽然例子并不复杂,因为是改造实话说开发过程中也遇到不少问题,而且本文原计划要实现能够在PageSlider的子页面中动态添加当前页码(如右图的1位置),但是因为实在不知道怎么获取当前页面的内容,最后用ToastDialog来实现了(即左侧图片下面页面所以提示),留个尾巴吧未来来实现,先继续往下走!
改造例子的时候深深的感受到什么叫“眼高手低”,看代码、抄代码感觉一看都懂,一动手要不不知如何下手,要不就是改错,但别灰心,谁让是新手!
只要不停下来,未来的路会更顺!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。