HarmonyOS三方件开发指南(18)-Flexbox流式布局组件

开发 OpenHarmony
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

[[394124]]

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

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

https://harmonyos.51cto.com

引言

上一篇给大家介绍底部导航栏的组件使用及开发指南,本篇将给大家带来另一个鸿蒙三方件的是实现:Flexbox,何为Flexbox,如果对Java的Swing比较熟悉的话一定不会陌生,就是控件根据ViewGroup的宽,自动的往右添加,如果当前行剩余空间不足,则自动添加到下一行。有点所有的控件都往左飘的感觉,第一行满了,往第二行飘~所以也叫流式布局。鸿蒙并没有提供流式布局,但是某些场合中,流式布局还是非常适合使用的,比如关键字标签,搜索热词列表等,比如下图:

这些都特别适合使用Flexbox,本篇会带领大家自己实现Flexbox,然后使用我们自己定义的Flexbox实现上面的标签效果。学会使用一个控件和学会写一个控件,我相信大家都明白,授人以鱼不如授人以渔。

接下来看下鸿蒙模拟器的实现效果,效果图如下:

图(1)默认标签状态

图(2)标签选中状态

VideoCache使用指南

Ø 新建工程, 添加组件Har包依赖

在应用模块中添加HAR,只需要将flexboxlibrary-debug.har复制到entry\libs目录下即可

Ø 修改配置文件

1. 在布局中添加如下代码:

  1. <com.istone.flexboxlibrary.HWFlowViewGroup 
  2.     ohos:id="$+id:viewgroup" 
  3.     ohos:height="match_content" 
  4.     ohos:width="match_parent" 
  5.     ohos:background_element="gray" 
  6.     ohos:orientation="vertical" 
  7.     /> 

2.在代码中通过以下方式使用:

  1. //mNames 是item的数据源,可以是任意需要显示的数据类型,根据实际情况去定义 
  2. parentLayout = (HWFlowViewGroup) findComponentById(ResourceTable.Id_viewgroup); 
  3. parentLayout.HWFlowViewGroup(getContext(), mNames, parentLayout); 
  4. parentLayout.setOnItemClickListener((Component view) -> { 
  5. //item点击之后的回调 
  6.     Text text = (Text)view
  7.     if(text.isSelected()){ 
  8.         text.setTextColor(Color.BLACK); 
  9.  
  10.     }else
  11.         text.setTextColor(Color.WHITE); 
  12.     } 
  13. }); 
  14. 1. 

VideoCache开发指南

在上述中,已经说明Flexbox 如何在开发过程中使用,接下来简单的分析下Flexbox 实现思路

1、对于Flexbox ,需要指定的LayoutConfig,我们目前只需要能够识别margin、padding即可

2、measureChild中计算所有childView的宽度,然后根据childView的宽度,计算当前每一行的宽度

3、最后根据计算之后的宽度,对中所有的childView进行布局。

以text为例,计算每个childView 的代码如下:

  1. private float measureChild(Text text) { 
  2.     Paint paint = new Paint(); 
  3.     paint.setTextSize(text.getTextSize()); 
  4.     float childWidth = paint.measureText(text.getText()); 
  5.     childWidth = childWidth + text.getPaddingLeft() + text.getPaddingRight() + text.getMarginLeft() + text.getMarginRight(); 
  6.     return childWidth; 
  7. 1. 

初始化每行的布局,代码如下:

  1. private DirectionalLayout initDirtLayout() { 
  2.     DirectionalLayout childLayout = new DirectionalLayout(mContext); 
  3.     childLayout.setOrientation(Component.HORIZONTAL); 
  4.     DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT); 
  5.     layoutConfig.setMargins(10, 10, 10, 10); 
  6.     childLayout.setLayoutConfig(layoutConfig); 
  7.     return childLayout; 

获取屏幕的宽度,代码如下:

  1. private void getParentWidthAndHeight() { 
  2.     Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(mContext); 
  3.     Point pt = new Point(); 
  4.     display.get().getSize(pt); 
  5.     mParentWidth = (int) pt.getPointX(); 

动态布局:

  1. private void initChildViews() { 
  2.     for (int i = 0; i < mNames.length; i++) { 
  3.         Text text = new Text(mContext); 
  4.         text.setId(i); 
  5.         text.setText(mNames[i]); 
  6.         text.setTextSize(100); 
  7.         text.setSelected(false); 
  8.         text.setTextColor(Color.WHITE); 
  9.         text.setPadding(10, 10, 10, 10); 
  10.         ShapeElement background = new ShapeElement(); 
  11.         background.setRgbColor(new RgbColor(205, 92, 92)); 
  12.         text.setBackground(background); 
  13.         DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT); 
  14.         layoutConfig.setMargins(20, 10, 20, 10); 
  15.         text.setLayoutConfig(layoutConfig); 
  16.  
  17.         if (i == 0) { 
  18.             childLayout = initDirtLayout(); 
  19.             mLineWidth = measureChild(text); 
  20.             childLayout.addComponent(text); 
  21.         } else { 
  22.             mLineWidth = mLineWidth + measureChild(text); 
  23.             if (mLineWidth > (mParentWidth - childLayout.getMarginLeft() - childLayout.getMarginRight())) { 
  24.                 mParentLayout.addComponent(childLayout); 
  25.                 childLayout = initDirtLayout(); 
  26.                 mLineWidth = measureChild(text); 
  27.             } 
  28.             childLayout.addComponent(text); 
  29.             if (i == mNames.length - 1) { 
  30.                 mParentLayout.addComponent(childLayout); 
  31.             } 
  32.         } 
  33.  
  34.         ComponentBean bean = new ComponentBean(text, false); 
  35.         list.add(bean); 
  36.  
  37.         text.setClickedListener(component -> { 
  38.             text.setSelected(!text.isSelected()); 
  39.             mOnItemClickListener.onItemClick(text); 
  40.         }); 
  41.     } 

定义接口,实现item的点击事件

  1. public interface OnItemClickListener { 
  2.     void onItemClick(Component view); 
  3.  
  4. public void setOnItemClickListener(OnItemClickListener onItemClickListener) { 
  5.     mOnItemClickListener = onItemClickListener; 

按照思路看下来,是不是很简单呢?我们只需要把握住如何计算childview 的宽度,以及什么情况下添加新的一行即可。

更多原创,请关注:https://harmonyos.51cto.com/column/30

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

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

https://harmonyos.51cto.com

 

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

2021-06-28 14:48:03

鸿蒙HarmonyOS应用

2021-02-04 09:45:19

鸿蒙HarmonyOS应用开发

2021-01-18 09:52:20

鸿蒙HarmonyOS开发

2021-01-12 12:04:40

鸿蒙HarmonyOS应用开发

2021-01-21 13:21:18

鸿蒙HarmonyOSPhotoview组件

2021-01-20 09:54:56

鸿蒙HarmonyOS开发

2021-03-01 09:48:24

鸿蒙HarmonyOS应用开发

2021-02-24 15:22:47

鸿蒙HarmonyOS应用开发

2021-05-12 15:17:39

鸿蒙HarmonyOS应用

2021-04-16 09:28:18

鸿蒙HarmonyOS应用

2021-01-13 09:40:31

鸿蒙HarmonyOS开发

2021-02-04 13:06:38

鸿蒙HarmonyOS应用开发

2021-01-22 17:33:03

鸿蒙HarmonyOS应用开发

2021-03-19 17:42:01

鸿蒙HarmonyOS应用开发

2021-02-26 14:15:27

鸿蒙HarmonyOS应用开发

2021-03-01 14:01:41

鸿蒙HarmonyOS应用开发

2021-03-31 09:50:25

鸿蒙HarmonyOS应用开发

2021-04-12 09:36:54

鸿蒙HarmonyOS应用

2021-07-28 09:40:04

鸿蒙HarmonyOS应用

2021-03-10 15:03:40

鸿蒙HarmonyOS应用
点赞
收藏

51CTO技术栈公众号