HarmonyOS PageSlider组件使用(二)Provider介绍

开发 前端 OpenHarmony
PageSliderProvider类提供页面项管理功能,例如计算可用视图的数量和在指定位置创建组件。您需要继承并实现PageSliderProvider,以便在不同的页面上显示多个视图。

[[422095]]

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

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

https://harmonyos.51cto.com

一、简要概述

PageSliderProvider是为PageSlider组件提供用于管理页面视图的页面适配器。

PageSliderProvider类提供页面项管理功能,例如计算可用视图的数量和在指定位置创建组件。您需要继承并实现PageSliderProvider,以便在不同的页面上显示多个视图。

PageSliderProvider类的使用比较简单,但在复杂业务场景下使用时,需要做的工作比较多,而且这些工作都有重复性。所以在编写本章节案例的同时,我对PageSliderProvider进行了一下通用封装,并且把代码共享到了码云Gitee上,同时将封装的代码打包成har包,提交到了Maven中央仓库,供大家使用。

码云Gitee仓库地址

二、方法介绍

需要掌握的PageSliderProvider类方法不多,一般只需要重写下面四个方法即可为PageSlider提供Page数据支持。

PageSliderProvider类还提供了Page页面数据刷新需要用到的方法,这部分方法可以相互配合,达到精准更新Page页面数据。

三、封装解析

PageSliderProvider是一个abstract抽象类,每次使用此类的时候都需要继承它,并重写相应的抽象方法。这种重复的工作,写多了,既繁琐,又浪费时间,降低开发效率。所以秉着高效易用的目的,先对PageSliderProvider进行一定封装。

数据源的封装。在常规业务开发模式中,为PageSliderProvider提供页面元数据是最基础的工作,一般都是将一个复杂的Object对象实例集合加入到一个List列表中。考虑数据的通用性,这里我们也将采用泛型来封装PageSliderProvider类。

  1. public abstract class BasePageSliderProvider<M> extends PageSliderProvider { 
  2.  
  3.     //页面加载数据源 
  4.     private final List<M> mPageSliderSourceData; 
  5.  
  6.     //构造函数初始化列表集合 
  7.     public BasePageSliderProvider() { 
  8.         this.mPageSliderSourceData = new ArrayList<>(); 
  9.     } 
  10.      
  11.     /** 
  12.      * 对外提供清除数据源的操作方法, 
  13.      * 
  14.      * 后续需要根据业务自行判断是否需要调用notifyDataChanged()方法 
  15.      */ 
  16.     public final void clearSourceData() { 
  17.         mPageSliderSourceData.clear(); 
  18.     } 
  19.  
  20.     /** 
  21.      * 对外提供设置/重置数据源的操作方法, 
  22.      * 
  23.      * 后续需要根据业务自行判断是否需要调用notifyDataChanged()方法 
  24.      * @param data 
  25.      */ 
  26.     public final void setSourceData(List<M> data) { 
  27.         if (!data.isEmpty()) { 
  28.             mPageSliderSourceData.clear(); 
  29.             mPageSliderSourceData.addAll(data); 
  30.         } 
  31.     } 
  32.  
  33.     /** 
  34.      * 对外追加数据源的操作方法,可能在加载更多数据的时候有用。 
  35.      * 
  36.      * 后续需要根据业务自行判断是否需要调用notifyDataChanged()方法 
  37.      * @param data 
  38.      */ 
  39.     public final void appendSourceData(List<M> data) { 
  40.         if (!data.isEmpty()) { 
  41.             mPageSliderSourceData.addAll(data); 
  42.         } 
  43.     } 
  44.  
  45.     /** 
  46.      * 对外提供删除指定数据源的操作方法, 
  47.      * 
  48.      * 后续需要根据业务自行判断是否需要调用notifyDataChanged()方法 
  49.      * @param data 
  50.      */ 
  51.     public final void removeSourceData(M data) { 
  52.         if (data != null) { 
  53.             mPageSliderSourceData.remove(data); 
  54.         } 
  55.     } 
  56.  
  57.     /** 
  58.      * 对外提供获取指定位置数据的操作方法 
  59.      * @param position 
  60.      * @return 
  61.      */ 
  62.     public final M getItem(int position) { 
  63.         return mPageSliderSourceData.get(position); 
  64.     } 
  65.  
  66.     /** 
  67.      * 并使用final修饰,防止子类继承重写,导致出现问题。 
  68.      * @return 
  69.      */ 
  70.     @Override 
  71.     public final int getCount() { 
  72.         return mPageSliderSourceData.size(); 
  73.     } 
  74.      
  75. }     

在重写PageSliderProvider类的getCount()抽象方法时,对此方法使用了final关键字修饰,目的是为了防止子类继承重写,导致出现问题。

页面视图组件的封装。页面视图组件是嵌入式设备应用开发中最需要关心的一件事情,嵌入式设备因内存资源是有限的的,而页面视图组件占用内存资源都还比较大,处理不好,甚至影响应用的流畅性和稳定性。所以在对页面视图组件封装时,需要考虑视图组件的快速创建和及时回收,防止内存泄露/溢出等问题。

在以往的应用开发经验中,ViewHolder绑定视图组件是一种非常高效解决视图组件回收复再利用的好模式。本次我们也使用这种ViewHolder模式来封装页面视图组件,并在PageSliderProvider类中进行简单的组件回收和再利用处理。

创建一个PageViewHolder类,用于绑定页面视图组件。在PageViewHolder类中进行简单的视图组件封装,业务开发中继承本类,去实现更多跟复杂的组件操作。

  1. public abstract class PageViewHolder { 
  2.  
  3.     protected final Component component; 
  4.  
  5.     public PageViewHolder(Component component) { 
  6.         this.component = component; 
  7.     } 
  8.  
  9.     /** 
  10.      * 返回绑定的视图组件 
  11.      * @return 
  12.      */ 
  13.     public final Component getComponent() { 
  14.         return component; 
  15.     } 

具体的业务开发中,使用的ViewHolder肯定是PageViewHolder的子类,是无法确定具体的实例对象类型的。所以在重写PageSliderProvider类的时候,我们也需要采用泛型来达到通用性。

页面视图组件的回收和再利用,常规简单操作我们都是使用列表或者队列进行存储,模拟回收站功能。在创建组件和销毁组件的方法中进行再利用和回收操作,已达到可以反复循环利用的目的,减少页面视图组件的多次创建带来的性能消耗。

  1. public abstract class BasePageSliderProvider<M, VH extends PageViewHolder> extends PageSliderProvider { 
  2.  
  3.     //页面PageViewHolder缓存,主要保存当前处于活跃状态的PageViewHolder对象 
  4.     private final HashMap<Integer, VH> mPageSliderComponentCache; 
  5.  
  6.     //页面PageViewHolder回收站 
  7.     private final Queue<VH> mPageSliderComponentRecyclers; 
  8.  
  9.      
  10.     public BasePageSliderProvider() { 
  11.         this.mPageSliderComponentCache = new HashMap<>(); 
  12.         this.mPageSliderComponentRecyclers = new LinkedBlockingQueue<>(); 
  13.     } 
  14.  
  15.     /** 
  16.      * 对外提供获取指定位置PageViewHoder对象的方法 
  17.      * @param position 
  18.      * @return 
  19.      */ 
  20.     public final VH getPageViewHolder(int position) { 
  21.         return mPageSliderComponentCache.get(position); 
  22.     } 
  23.  
  24.     @Override 
  25.     public Object createPageInContainer(ComponentContainer componentContainer, int index) { 
  26.         if (componentContainer == null || index >= getCount()) { 
  27.             return Optional.empty(); 
  28.         } 
  29.  
  30.         //从PageViewHolder回收站中获取对象,如果没有,创建新的PageViewHolder实例 
  31.         VH pageViewHolder = mPageSliderComponentRecyclers.poll(); 
  32.         if (pageViewHolder == null) { 
  33.             pageViewHolder = onCreatePageViewHolder(componentContainer, index); 
  34.         } 
  35.  
  36.         onBindPageViewHolder(pageViewHolder, index); 
  37.         componentContainer.addComponent(pageViewHolder.getComponent()); 
  38.         //添加到缓存中 
  39.         mPageSliderComponentCache.put(index, pageViewHolder); 
  40.  
  41.         return pageViewHolder; 
  42.     } 
  43.  
  44.     @Override 
  45.     public void destroyPageFromContainer(ComponentContainer componentContainer, int index, Object object) { 
  46.         if (componentContainer == null || index >= getCount()) { 
  47.             return
  48.         } 
  49.  
  50.         if (object instanceof PageViewHolder) { 
  51.             componentContainer.removeComponent(((PageViewHolder) object).getComponent()); 
  52.             mPageSliderComponentCache.remove(index); 
  53.             //回收已经被销毁的PageViewHolder 
  54.             mPageSliderComponentRecyclers.offer((VH) object); 
  55.         } 
  56.     } 
  57.  
  58.     @Override 
  59.     public boolean isPageMatchToObject(Component component, Object object) { 
  60.         if (object instanceof PageViewHolder) { 
  61.             return component == ((PageViewHolder) object).getComponent(); 
  62.         } 
  63.         return component == object; 
  64.     } 
  65.  
  66.     /** 
  67.      * 创建并返回一个PageViewHolder对象 
  68.      * @param componentContainer 
  69.      * @param position 
  70.      * @return 
  71.      */ 
  72.     protected abstract VH onCreatePageViewHolder(ComponentContainer componentContainer, int position); 
  73.  
  74.     /** 
  75.      * 为指定位置的PageViewHolder对象绑定数据 
  76.      * @param holder 
  77.      * @param position 
  78.      */ 
  79.     protected abstract void onBindPageViewHolder(VH holder, int position); 
  80.      

四、应用实战

经过一系列的简单封装,PageSliderProvider类使用起来就简单了。我们就不需要再去为页面数据和组件的绑定,重复的去造轮子。直接从BasePageSliderProvider类继承,重写onCreatePageViewHolder和onBindPageViewHolder两个方法,直接绑定数据即可完成PageSlider组件的数据和页面组件的提供。

1.在工程layout目录下的创建Page页面布局文件。比如:component_page.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DependentLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_parent" 
  5.     ohos:width="match_parent"
  6.  
  7.     <Text 
  8.         ohos:id="$+id:text_component" 
  9.         ohos:height="match_parent" 
  10.         ohos:width="match_parent" 
  11.         ohos:text_size="32fp" 
  12.         ohos:text_font="sans-serif-medium" 
  13.         ohos:text_weight="800" 
  14.         ohos:text_color="#ffffff" 
  15.         ohos:text_alignment="center"/> 
  16.  
  17. </DependentLayout> 

2.继承PageViewHolder类,绑定Page页面布局组件。比如:CasePageViewHolder

  1. private static class CasePageViewHolder extends PageViewHolder { 
  2.  
  3.     private Text mTextCom; 
  4.  
  5.     public CasePageViewHolder(Component component) { 
  6.         super(component); 
  7.         mTextCom = (Text) component.findComponentById(ResourceTable.Id_text_component); 
  8.     } 
  9.  
  10.     public void setText(String text) { 
  11.         mTextCom.setText(text); 
  12.     } 
  13.  
  14.     public void setBackground(RgbColor color) { 
  15.         ShapeElement element = new ShapeElement(); 
  16.         element.setShape(ShapeElement.RECTANGLE); 
  17.         element.setRgbColor(color); 
  18.         mTextCom.setBackground(element); 
  19.     } 

3.继承BasePageSliderProvider类,绑定Page页面数据源和PageViewHolder。

  1. private static class CasePageSliderProvider extends BasePageSliderProvider<PageInfo, CasePageViewHolder> { 
  2.  
  3.     @Override 
  4.     protected CasePageViewHolder onCreatePageViewHolder(ComponentContainer componentContainer, int position) { 
  5.         LayoutScatter layoutScatter = LayoutScatter.getInstance(componentContainer.getContext()); 
  6.         Component component = layoutScatter.parse(ResourceTable.Layout_component_page, componentContainer, false); 
  7.         return new CasePageViewHolder(component); 
  8.     } 
  9.  
  10.     @Override 
  11.     protected void onBindPageViewHolder(CasePageViewHolder holder, int position) { 
  12.         PageInfo pageInfo = getItem(position); 
  13.         holder.setText(pageInfo.getContent()); 
  14.         holder.setBackground(pageInfo.getColor()); 
  15.     } 

4.初始Page页面元数据和PageSlider组件,并将PageSliderProvider对象绑定到PageSlider组件中。

  1. public class MainAbilitySlice extends AbilitySlice { 
  2.  
  3.     private PageSlider mPageSlider; 
  4.     private CasePageSliderProvider mPageSliderProvider; 
  5.  
  6.     @Override 
  7.     public void onStart(Intent intent) { 
  8.         super.onStart(intent); 
  9.         super.setUIContent(ResourceTable.Layout_ability_main); 
  10.         mPageSlider = (PageSlider) findComponentById(ResourceTable.Id_page_slider_component); 
  11.  
  12.         mPageSliderProvider = new CasePageSliderProvider(); 
  13.         mPageSliderProvider.setSourceData(createAndInitPageData()); 
  14.         mPageSlider.setProvider(mPageSliderProvider); 
  15.     } 
  16.  
  17.     //初始化Page页面元数据 
  18.     private List<PageInfo> createAndInitPageData(){ 
  19.         List<PageInfo> initData = new ArrayList<>(); 
  20.         for (int i = 0; i < 15; i++) { 
  21.             PageInfo pageInfo = new PageInfo(); 
  22.             char tempChar = (char) (new Random().nextInt(26) + 65); 
  23.             pageInfo.setContent("Case " + String.valueOf(tempChar)); 
  24.             pageInfo.setColor(new RgbColor( 
  25.                     new Random().nextInt(255), 
  26.                     new Random().nextInt(255), 
  27.                     new Random().nextInt(255))); 
  28.             initData.add(pageInfo); 
  29.         } 
  30.         return initData; 
  31.     } 
  32.     
  33.     private static class PageInfo { 
  34.  
  35.         private String content; 
  36.         private RgbColor color; 
  37.  
  38.         public String getContent() { 
  39.             return content; 
  40.         } 
  41.  
  42.         public void setContent(String content) { 
  43.             this.content = content; 
  44.         } 
  45.  
  46.         public RgbColor getColor() { 
  47.             return color; 
  48.         } 
  49.  
  50.         public void setColor(RgbColor color) { 
  51.             this.color = color; 
  52.         } 
  53.     } 

五、总结

这里只是简单的对PageSliderProvider类进行了一下封装试用,并将代码提交到了码云Gitee仓库,并进行了Maven中央仓库管理。PageSliderProvider类其实还可以进行更多功能改造,封装的更加高效易用,如果有意向,可以直接在码云Gitee仓库进行代码共享哦。

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

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

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2009-07-21 10:40:36

ASP.NET Pro

2021-09-30 10:04:01

鸿蒙HarmonyOS应用

2009-11-18 16:51:21

Oracle Prov

2018-04-20 15:24:55

DockerfileDocker镜像

2009-12-29 10:40:36

ADO组件

2023-09-21 07:06:17

PSDriveProvider

2021-10-14 15:14:36

鸿蒙HarmonyOS应用

2009-07-10 18:06:59

JTree Swing

2011-04-28 10:41:12

simpleframeSimple

2009-07-17 14:38:51

轻量级Swing组件

2021-09-13 15:17:28

鸿蒙HarmonyOS应用

2009-07-17 11:13:46

AWT和SwingSwing组件

2021-09-06 15:31:01

鸿蒙HarmonyOS应用

2020-11-16 09:50:43

hpm-cli

2021-03-18 09:36:02

鸿蒙HarmonyOS应用

2009-11-18 16:43:59

2009-08-25 13:38:35

C# Timer组件

2013-01-10 13:50:25

Android开发组件

2011-09-13 15:35:40

Widget

2017-01-19 18:58:11

iOS组件化方案
点赞
收藏

51CTO技术栈公众号