HarmonyOS NEX 鸿蒙select选择器

71 阅读2分钟

先看效果 微信图片_20250328142742.jpg

1.在目录ets/components/hSelect下创建index.ets

//弹窗具体内容
@CustomDialog
struct SelectDialogDate {
  controller?: CustomDialogController
  @State listData:Array<ListData> = [] // 列表
  @State list:string[]=[] // 列表
  @State listValue: string = "";
  @State index: number = 0;


  cancel: () => void = () => {
  }
  confirm: (data:ListData) => void = () => {
  }

  // 提交数据
  onSubmit(){
    this.listData.map(item=>{
      if(item.value === this.listValue){
        this.confirm(item) //回传日期到父组件
        this.controller?.close()
        return
      }
    })

  }

  aboutToAppear(): void {
    this.listData.map((item: ListData) => {
      this.list.push(item.value)
    })

    if(this.listValue){
      this.list.map((res,i)=>{
        if(res === this.listValue){
          this.index = i
          console.log('this.index',this.index)
        }
      })
    }
  }

  // 初始化默认选中
  initDefaultTime(){

  }

  build() {
    Column() {
      Row(){
        Button('取消', { type: ButtonType.Normal, stateEffect: true })
          .margin(0)
          .borderRadius(6)
          .backgroundColor('#fff')
          .fontColor('#aaa')
          .fontSize(14)
          .onClick(()=>{
            this.controller?.close()
          })
        Button('确定', { type: ButtonType.Normal, stateEffect: true })
          .margin(0)
          .backgroundColor('#fff')
          .fontColor('#3C7FFF')
          .fontSize(14)
          .onClick(()=>{
            this.onSubmit()
            this.controller?.close()
          })
      }.width('100%').justifyContent(FlexAlign.SpaceBetween)

      Divider().color('#EEE').strokeWidth(1)

      // 滚动选中区域
      Flex(){
        TextPicker({ range: this.list, selected: this.index})
          .width('100%')
          .canLoop(false)//不循环
          .divider({
            strokeWidth: 1,
            startMargin: 0,
            endMargin: 0,
            color:'#eee'
          })
          .onChange((value: string | string[], index: number | number[]) => {
            this.index= index as number
            this.listValue = value as string

          })
          .defaultPickerItemHeight(40)
          .textStyle({color:'#cccccc', font: {size: 15, weight: 400}})
          .selectedTextStyle({color: '#555555', font: {size: 15}})
      }
    }.width('100%')
    .padding({bottom:40,top:5})
    .height(300)
    .backgroundColor('#fff')
  }
}

//定义controller对象 主要作用父子通信 父组件调用子组件方法 唤醒弹窗
export  class SelectController {
  ShowDialog = (value?: string) => {
  }
}

//弹窗控制逻辑
@Component
export  struct HSelect {
  private controller: SelectController = new SelectController();
  CustomDialogController: CustomDialogController | null =null ;
  @State list: Array<ListData> = [];
  @Link value: string;
  cancel?: () => void
  confirm?: (data:ListData) => void = () => {
  }
  // 打开显示弹窗
  private async  open(value?: object){
    console.log("valuevaluevalue",this.value)
    this.CustomDialogController?.open()
  }
  aboutToAppear(): void {
    if (this.controller) {
      //给controller对应的方法赋值
      this.controller.ShowDialog = this.open.bind(this); //这里需要注意 用了  bind改变 this 指向
    }
    console.log('this.value'+this.value)
    this.CustomDialogController=  new CustomDialogController({
      builder: SelectDialogDate({
        listData: this.list,
        listValue: this.value,
        cancel: this.cancel,
        confirm: this.confirm,
      }),
      autoCancel: true,
      onWillDismiss:(dismissDialogAction: DismissDialogAction)=> {
        if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
          dismissDialogAction.dismiss()
        }
        if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
          dismissDialogAction.dismiss()
        }
      },
      alignment: DialogAlignment.Bottom,
      offset: { dx: 0, dy:  0},
      height: 200,
      customStyle: true,//这里为true 样式才可以完全自定义
    })
  }
  aboutToDisappear() {
    this.CustomDialogController = null // 将dialogController置空
  }
  
  build() { //因为用的 自定义弹窗功能,所以这下面可以为空
  }
}

export  class ListData {
  public key: string
  public value: string
  constructor(key: string, value: string) {
    this.key = key
    this.value = value
  }
}

2.在页面调用

import { SelectController, HSelect, ListData } from '../../components/hSelect'

@Component
export struct Home {

  @State DeptListSelect: Array<ListData> = [
    new ListData('0','所有部门'),
    new ListData('1','策划部'),
    new ListData('0','运营部'),
    new ListData('0','测试部'),
    new ListData('0','开发部'),
    new ListData('0','财务部'),
    new ListData('0','开发办公室'),
  ]
  @State deptName: string = "所有部门";

  @State SelectDialogRef: SelectController = new SelectController();//用于调用子组件的方法 唤醒弹窗

  @Styles buttonStyles() {
    .borderRadius(0)
    .backgroundColor('#fff')
    .margin({left:15})
    .height(35)
    .border({
      width: 1,          // 边框宽度
      color: '#cccccc',  // 边框颜色
      style: BorderStyle.Solid // 边框样式(Solid、Dashed、Dotted)
    })
  }

  build() {
    Column(){
      Column(){
        Row(){
          Button(this.deptName, { type: ButtonType.Normal, stateEffect: true })
            .fontSize(12)
            .fontWeight(400)
            .fontColor('#000')
            .buttonStyles()
            .onClick(()=>{
              this.SelectDialogRef.ShowDialog()
            })
        }.backgroundColor('#F1F3F4').width('100%').height(50).backgroundColor('#fff')
      }.layoutWeight(1).backgroundColor('#ffffff').clip(true)

      HSelect({
        list:this.DeptListSelect,
        value:this.deptName,
        controller:this.SelectDialogRef,
        confirm:(data)=>{
          this.deptName = data.value
        }
      })
    }
  }
}