【入门到精通】鸿蒙next开发:基于ArkUI组件picker的自定义实现

往期鸿蒙5.0全套实战文章必看:(文中附带全栈鸿蒙5.0学习资料)


基于ArkUI组件picker的自定义实现

场景一:自定义TextPickerDialog

方案:

开发者对于Picker这块常常会有一个误区,在使用Picker这块弹窗的时候优先会使用封装好的PikcerDialog类组件;但是需要注意的是,PikcerDialog类的组件是和系统颜色保持一致的,并不支持自定义;当需要自定义Picker弹窗时,优先考虑自行封装。所以,开发者使用Picker弹窗的时候优先考虑自己使用Picker类组件自行封装。

主要方案就是使用全局自定义弹窗PromptAction.openCustomDialog封装TextPicker组件,然后达成像TextPickerDialog同样的功能,拥有更灵活的自定义能力。

核心代码:

private selectDialogIn: number = 0 
private daysDialogIn: string[] = Array(31).fill(0).map((v: string, i) => i + 1).map(n => n.toString()); 
@State showDayDialogIn: string = '' 
 
@Builder 
customDialogComponent() { 
  Column() { 
    //orange area 
    Row() { 
      Text(this.showDayDialogIn).fontColor('#FF9A3C').fontSize(15).margin({ left: 10 }) 
      Text('天以后可以修改').fontColor('#FF9A3C').fontSize(15) 
    } 
    .height(50).width('100%').alignItems(VerticalAlign.Center).backgroundColor('#FEF2E5') 
 
    // cancal area 
    Row() { 
      Text('取消').fontColor('#9C9C9C').fontSize(20).margin({ left: 10 }) 
        .onClick(() => { 
          promptAction.closeCustomDialog(this.customDialogComponentId) 
          this.showDayDialogIn = '' 
        }) 
      Text('选择持续天数').fontColor('#2D2D2D').fontSize(17) 
      Text('确定') 
        .fontColor('#507DAF') 
        .fontSize(20) 
        .fontWeight(FontWeight.Bold) 
        .margin({ right: 10 }) 
        .onClick(() => { 
          this.showDayDialogIn = '' 
          promptAction.closeCustomDialog(this.customDialogComponentId) 
        }) 
    } 
    .alignItems(VerticalAlign.Center) 
    .justifyContent(FlexAlign.SpaceBetween) 
    .width('100%') 
    .height(60) 
 
    // textpicker area 
    Row() { 
      TextPicker({ range: this.daysDialogIn, selected: this.selectDialogIn }) 
        .onChange((value: string | string[], index: number | number[]) => { 
          this.showDayDialogIn = value.toString() 
          console.info('Picker item changed, value: ' + value + ', index: ' + index) 
        }) 
        .canLoop(false) 
        .divider({ 
          strokeWidth: '2px', 
          startMargin: 20, 
          endMargin: 20, 
          color: '#33000000' 
        }) 
        .gradientHeight('60%') 
        .disappearTextStyle({ color: Color.Black, font: { size: 20, weight: FontWeight.Lighter } }) 
        .textStyle({ color: Color.Black, font: { size: 20, weight: FontWeight.Lighter } }) 
        .selectedTextStyle({ color: Color.Black, font: { size: 20, weight: FontWeight.Normal } }) 
      Text('天').fontSize(20).fontColor(Color.Black) 
    }.width('100%').alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center).margin({ top: 10 }) 
  }.width('100%').height(360) 
}

场景二:自定义CalendarPickerDialog

效果:

      效果说明:此处的场景是一个日历选择弹窗,实现了一个类考勤打卡的demo。

37.gif

方案:

参考场景1方案。此处的picker弹窗也是基于全局自定义弹窗进行封装的,只是不同上面的自定义TextPickerDialog,calendar没有选择使用官方的calendarPicker组件,而是使用三方库直接封装好的,以下demo是参考三方库@ohmos/calendar实现;当然,开发者也可以自行到三方库中搜寻日历相关关键字,然后挑选适合自己需求的三方库。

核心代码:

@Builder 
NormalCalendarBuilder() { 
  Column() { 
    Row() { 
      Text('取消').fontColor('#9C9C9C').fontSize(20).margin({ left: 10 }) 
        .onClick(() => { 
          promptAction.closeCustomDialog(this.normalCalendarDialogId) 
        }) 
      Text('请选择日期').fontSize(17).fontColor('#00aa00').fontWeight(FontWeight.Medium) 
      Text('确定') 
        .fontColor('#507DAF') 
        .fontSize(20) 
        .fontWeight(FontWeight.Bold) 
        .margin({ right: 10 }) 
        .onClick(() => { 
          promptAction.closeCustomDialog(this.normalCalendarDialogId) 
        }) 
    } 
    .alignItems(VerticalAlign.Center) 
    .justifyContent(FlexAlign.SpaceBetween) 
    .width('100%') 
    .height(60) 
 
    HmCalendar({ 
      color: '#00aa00', 
      selectedDays: this.normalCalendarSelectedDay, 
      onClickDate: (date: string) => { 
        let today: HmCalendarSelectedDay = { date: date } 
        if (this.normalCalendarSelectedDay.length === 0) { 
          this.normalCalendarSelectedDay.push(today) 
        } 
        // 判断今天是否已经打卡 
        if (!this.normalCalendarSelectedDay.includes(today)) { 
          this.normalCalendarSelectedDay.push(today) 
        } 
      } 
    }) 
      .borderRadius(8) 
      .border({ width: 0.5, color: '#ededed' }) 
      .shadow({ color: '#ededed', radius: 16 }) 
      .height('50%') 
  } 
  .width('100%') 
}

场景三:多列的TextPicker的实现

效果:

      效果说明:文档当中只有最多3列的TextPicker,此处是4列的TextPicker。

38.jpg

方案:

如下代码所示,传入几列的数据,TextPicker就会渲染出几列的数据;且TextPicker中的range是支持二维数组的。

核心代码:

@Entry 
@Component 
export struct MultipleColumnsTextPicker { 
  private cascade: TextCascadePickerRangeContent[] = [ 
    { 
      text: '辽宁省', 
      children: [{ 
        text: '沈阳市', 
        children: [{ 
          text: '沈河区', 
          children: [{ text: '大西街道' }, 
            { text: '滨河街道' }, 
            { text: '万莲街道' }, 
            { text: '大南街道' }, 
            { text: '山东庙街道' }, 
            { text: '朱剪炉街道' }, 
            { text: '东陵街道' }] 
        }, { text: '和平区' }, { text: '浑南区' }] 
      }, 
        { text: '大连市', children: [{ text: '中山区' }, { text: '金州区' }, { text: '长海县' }] }] 
    }, 
    { 
      text: '吉林省', 
      children: [{ text: '长春市', children: [{ text: '南关区' }, { text: '宽城区' }, { text: '朝阳区' }] }, 
        { text: '四平市', children: [{ text: '铁西区' }, { text: '铁东区' }, { text: '梨树县' }] }] 
    }, 
    { 
      text: '黑龙江省', 
      children: [{ text: '哈尔滨市', children: [{ text: '道里区' }, { text: '道外区' }, { text: '南岗区' }] }, 
        { text: '牡丹江市', children: [{ text: '东安区' }, { text: '西安区' }, { text: '爱民区' }] }] 
    } 
  ] 
 
  build() { 
    NavDestination() { 
      Column() { 
        Row() { 
          Text('4列TextPicker实现方式') 
        } 
        .width('100%') 
        .height(70) 
        .justifyContent(FlexAlign.SpaceAround) 
        .alignItems(VerticalAlign.Center) 
 
        TextPicker({ range: this.cascade }) 
          .onChange((value: string | string[], index: number | number[]) => { 
            console.info('TextPicker 多列联动:onChange ' + JSON.stringify(value) + ', ' + 'index: ' + 
            JSON.stringify(index)) 
          }) 
      } 
    } 
  } 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值