基于HarmonyOS鸿蒙Next ArkUI组件picker的自定义实现

基于HarmonyOS鸿蒙Next 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

方案:

参考场景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的实现

方案:

如下代码所示,传入几列的数据,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))
          })
      }
    }
  }
}
1 回复

更多关于基于HarmonyOS鸿蒙Next ArkUI组件picker的自定义实现的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


总结的仔细,厉害厉害

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!