鸿蒙ArkUI封装的复选组件

简介: 本文介绍了如何对鸿蒙系统中的官方复选组件进行封装,以解决多选项列表复用不便的问题,实现点击标签文本选择功能,选中状态通过图片区分显示和隐藏。

鸿蒙ArkUI封装的复选组件,官方提供了复选组件,不方便多选项列表复用,我们为此进行了封装。支持点击标签文本选中,其中显示选中非选中采用图片的方式。

import {IDynamicObject} from './IType'
/**
 * 复选
 */
@Component
export default  struct DiygwCheckbox{
 
  //绑定的值
  @Link @Watch('onValue') value:string[];
  // 保存所有单选框的名称
  @Link list: IDynamicObject[];
  // 隐藏值
  @State valueField: string = 'value';
  // 显示值
  @State labelField: string = 'label';
  // 选中/未选中状态下的图标
  @State checkedValues: Resource[] = [];
  //选中图标
  @State checkedImg: Resource = $r('app.media.checkboxon');
  //未选中图标
  @State noCheckedImg: Resource = $r('app.media.checkbox');
  //未选中图标
  @State labelImg: Resource = $r('app.media.user');
  //是否文本图片
  @State isLabelImg: boolean = false;
  @State labelImgWidth: number = 20;
  @State labelImgHeight: number = 20;
  //标题文本
  @State label:string = '多选';
  //水平状态时,文本占大小
  @State labelWidth:number = 80;
  //是否标题文本换行
  @State isWrapLabel:boolean = false;
  //是否标题文本
  @State isLabel:boolean = true;
  //标题颜色
  @State labelColor:string = "#333333";
  //自动标题长度
  @State isLabelAuto:boolean = false;
  //文本字体大小
  @State textSize:number = 14;
  //选中图版本大小
  @State imgSize:number = 28;
  //每个占比
  @State itemWidth:string = '33%';
  //每行个数
  @State col:number = 3;
  //组件内边距
  @State leftRightPadding:number = 16;
  @State topBottomPadding:number = 6;
  @State isBorder:boolean = true;
  //初始化选中
  initCheck(){
    for (let i = 0; i < this.list.length; i++) {
      if(this.value.includes(this.list[i][this.valueField])) {
        this.checkedValues[i] = this.checkedImg;
      }else{
        this.checkedValues[i] = this.noCheckedImg;
      }
    }
  }
  
  //监听选中
  onValue() {
     this.initCheck()
  }
 
  onChecked(index: number){
    //点击文本选中当前复选框
    if(this.checkedValues[index]==this.checkedImg){
      this.checkedValues[index] = this.noCheckedImg
      let findIndex = this.value.indexOf(this.list[index][this.valueField]);
      this.value.splice(findIndex,1);
    }else{
      this.checkedValues[index] = this.checkedImg;
      this.value.push(this.list[index][this.valueField]);
    }
 
  }
 
  build() {
    Flex({
      alignItems:this.isWrapLabel?ItemAlign.Start:ItemAlign.Center,
      direction:this.isWrapLabel?FlexDirection.Column:FlexDirection.Row,
      justifyContent:FlexAlign.Start
    }){
 
      if(this.isLabel){
        Row(){
          if(this.isLabelImg){
            Image(this.labelImg)
              .width(this.labelImgWidth)
              .height(this.labelImgHeight)
              .margin({ left:3 }).flexShrink(0)
          }
          if(this.isLabelAuto){
            Text(this.label).flexShrink(0).fontColor(this.labelColor).fontSize(this.textSize).margin({
              bottom:this.isWrapLabel?10:0,
              right:10,
            }).textAlign(TextAlign.Start);
          }else{
            Text(this.label).fontColor(this.labelColor).width(this.isWrapLabel?'100%':this.labelWidth).fontSize(this.textSize).margin({
              bottom:this.isWrapLabel?10:0
            }).textAlign(TextAlign.Start);
          }
        }.margin({
          top:this.isWrapLabel?10:0
        })
      }
      Flex({
        wrap:FlexWrap.Wrap
      }){
        ForEach(this.list, (item: any,index: number) => {
            Row(){
              Image(this.checkedValues[index])
                .borderRadius('50%')
                .size({width: this.imgSize , height: this.imgSize}).margin({
                top:1,
                bottom:1
              })
              Text(item[this.labelField])
                .fontSize(this.textSize)
                .margin({left: 10})
            }.onClick(()=>{
              this.onChecked(index)
            }).width(this.itemWidth)
        })
      }.width('100%')
    }.borderWidth({
      bottom: this.isBorder?1:0
    }).borderColor({
      bottom: "#eee"
    }).borderStyle(BorderStyle.Solid).height(Math.ceil(this.list.length/this.col)*30+(this.isWrapLabel?30:10)+this.topBottomPadding*2).padding({left:this.leftRightPadding,right:this.leftRightPadding,top:this.topBottomPadding,bottom:this.topBottomPadding})
    .onAppear(() => {
      let widths=['100%','50%','33%','25%']
      let col = widths.indexOf(this.itemWidth) + 1
      this.col = col
      this.initCheck()
    })
  }
}

目录
相关文章
|
5天前
「Mac畅玩鸿蒙与硬件46」UI互动应用篇23 - 自定义天气预报组件
本篇将带你实现一个自定义天气预报组件。用户可以通过选择不同城市来获取相应的天气信息,页面会显示当前城市的天气图标、温度及天气描述。这一功能适合用于动态展示天气信息的小型应用。
89 38
|
2天前
|
JavaScript Java 容器
鸿蒙应用开发从入门到入行 - 篇4:层叠布局、自定义组件、ForEach
导读:在本篇文章里,您将掌握层叠布局、自定义组件的用法,特别是自定义组件将来的开发中必然会用,其中应该特别关注自定义组件的一些规范与装饰器。
23 7
鸿蒙应用开发从入门到入行 - 篇4:层叠布局、自定义组件、ForEach
|
1天前
鸿蒙开发:一个轻盈的上拉下拉刷新组件
在和可滑动组件使用的时候,记得一定要和nestedScroll属性配合使用,用于解决滑动冲突,除此之外,还需要传递滑动组件的scroller属性,用于手势操作。
鸿蒙开发:一个轻盈的上拉下拉刷新组件
|
1天前
|
索引
【HarmonyOS Next开发】日历组件详细日界面组件
原生UI没有提供日历相关的组件,于是手撸了详细页面的日程。一开始打算使用list加tab的方式来实现切换的效果,但是list的切换是没有办法确定当前展示的索引的,所以没有办法实现日历内容动态添加等效果。在业内大佬的指导下,使用了两个swiper组件分别实现周和日的切换,实现了想要的效果
14 6
|
28天前
|
UED
「Mac畅玩鸿蒙与硬件31」UI互动应用篇8 - 自定义评分星级组件
本篇将带你实现一个自定义评分星级组件,用户可以通过点击星星进行评分,并实时显示评分结果。为了让界面更具吸引力,我们还将添加一只小猫图片作为评分的背景装饰。
71 6
|
1月前
|
前端开发 开发者
「Mac畅玩鸿蒙与硬件22」鸿蒙UI组件篇12 - Canvas 组件的动态进阶应用
在鸿蒙应用中,Canvas 组件可以实现丰富的动态效果,适合用于动画和实时更新的场景。本篇将介绍如何在 Canvas 中实现动画循环、动态进度条、旋转和缩放动画,以及性能优化策略。
55 6
|
1月前
|
前端开发 开发者
「Mac畅玩鸿蒙与硬件23」鸿蒙UI组件篇13 - 自定义组件的创建与使用
自定义组件可以帮助开发者实现复用性强、逻辑清晰的界面模块。通过自定义组件,鸿蒙应用能够提高代码的可维护性,并简化复杂布局的构建。本篇将介绍如何创建自定义组件,如何向组件传递数据,以及如何在不同页面间复用这些组件。
48 5
|
1天前
【HarmonyOS Next开发】:ListItemGroup使用
通过使用ListItemGroup和AlphabetIndexer两种类型组件,实现带标题分类和右侧导航栏的页面
81 61
|
1天前
|
安全 数据安全/隐私保护
鸿蒙开发:一文了解软键盘相关
软键盘最主要的就是合理的进行避让,不能遮挡可输入组件,再有多个输入框的时候,需要动态的进行设置高度,这一点需要注意。
鸿蒙开发:一文了解软键盘相关
|
2天前
|
开发框架 前端开发 JavaScript
uniapp开发鸿蒙,是前端新出路吗?
相信不少前端从业者一听uniapp支持开发鸿蒙Next后非常振奋。猫林老师作为7年前端er也是非常激动,第一时间体验了下。在这里也给大家分享一下我的看法
32 17

热门文章

最新文章