文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-12-03 06:58

关注

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

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

https://harmonyos.51cto.com

引言

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

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

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

图(1)默认标签状态

图(2)标签选中状态

VideoCache使用指南

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

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

Ø 修改配置文件

在布局中添加如下代码:

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

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

  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 实现思路

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

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

最后根据计算之后的宽度,对中所有的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 = 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

 

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯