HarmonyOS 使用TextPickerDialog.show方法onchange的时候修改range的参数怎么让弹窗中的内容也改变?

使用TextPickerDialog.show方法onchange的时候修改range的参数怎么让弹窗中的内容也改变?

比如地址选择器的实现,省份选择后市区列对应的内容需要改变。

demo实现:

interface btnParams {
  title: string;
  color: string
}

interface resultParams { value: Date; }

interface DatePickerParams {
  pattern?: string;
  titleBtn?: btnParams;
  leftBtn?: btnParams;
  rightBtn?: btnParams;
  maxDate?: number; // 最大日期时间戳
  minDate?: number; // 最小日期时间戳
  date?: number; // 当前显示日期时间戳
  callback?: (result: resultParams) => void;
}
const fieldMap: Record<string, string> = {
  'yyyy': 'year',
  'YYYY': 'year',
  'MM': 'month',
  'dd': 'day',
  'DD': 'day',
  'HH': 'hour',
  'hh': 'hour',
  'mm': 'minute',
  'ss':'second'
};


export async function SuiDatePicker(options: WosaifuncOptions) {

  let pickerParams: DatePickerParams = options.params as DatePickerParams;

  console.log('pickerParams',JSON.stringify(pickerParams))

  const fields = pickerParams.pattern?.split(/[- :]/).map(part => fieldMap[part]); // 根据 pattern 拆分字段
  const maxDate:Date = new Date(pickerParams.maxDate ? pickerParams.maxDate* 1000 : '');
  const minDate:Date = new Date(pickerParams.minDate ? pickerParams.minDate*1000 : '1970-1-1');
  const selDate:Date = new Date(pickerParams.date ? pickerParams.date*1000 : '');

  console.log('selDate',JSON.stringify(selDate))
  console.log('fields',JSON.stringify(fields))
  let selectedDate: Record<string, string> = {
    "year":selDate.getFullYear().toString(),
    "month": (selDate.getMonth() + 1).toString(),
    "day": selDate.getDate().toString(),
    "hour": selDate.getHours().toString(),
    "minute": selDate.getMinutes().toString(),
    "second": selDate.getSeconds().toString(),
  };

  let generateRange: Function = (min: number, max: number, current: number): string[]=> {
    let range:string[] = [];
    for (let i = min; i <= max; i++) {
      range.push(i+'');
    }
    return range;
  }

  let updateRanges: Function = (field: string, value: string) => {
    selectedDate[field] = value;

    if (field === 'year') {
      ranges.month = generateRange(1, 12, selectedDate.month);
      ranges.day = generateRange(1, getDaysInMonth(selectedDate.year, selectedDate.month), selectedDate.day);
    } else if (field === 'month') {
      ranges.day = generateRange(1, getDaysInMonth(selectedDate.year, selectedDate.month), selectedDate.day);
    }
  }

  let getDaysInMonth: Function = (year: number, month: number): number=>{
    return new Date(year, month, 0).getDate();
  }

  let formatSelectedDate = (selectedDate: Record<string, string>, pattern: string): string=>{
    const dateComponents: Record<string, string> = {
      'yyyy': selectedDate.year,
      'YYYY': selectedDate.year,
      'MM': selectedDate.month,
      'dd': selectedDate.day,
      'DD': selectedDate.day,
      'HH': selectedDate.hour,
      'hh': selectedDate.hour,
      'mm': selectedDate.minute,
      'ss':selectedDate.second
    };

    return pattern.replace(/yyyy|YYYY|MM|dd|DD|HH|hh|mm|ss/g, match => dateComponents[match]);
  }
  let getRanges = (date: Record<string, string>, minDate: Date, maxDate: Date):Record<string, string[]> => {
    return {
      "year": generateRange(minDate.getFullYear(), maxDate.getFullYear(), date.year),
      "month": generateRange(1, 12, date.month),
      "day": generateRange(1, getDaysInMonth(date.year, date.month), date.day),
      "hour": generateRange(0, 23, date.hour),
      "minute": generateRange(0, 59, date.minute),
      "second": generateRange(0, 59, date.second),
    };
  }


  let ranges: Record<string, string[]> = {
    "year": generateRange(minDate.getFullYear(), maxDate.getFullYear(), selectedDate.year),
    "month": generateRange(1, 12, selectedDate.month),
    "day": generateRange(1, 31, selectedDate.day),
    "hour": generateRange(0, 23, selectedDate.hour),
    "minute": generateRange(0, 59, selectedDate.minute),
    "second": generateRange(0, 59, selectedDate.second),
  };


  console.log('selectedDate',JSON.stringify(selectedDate))
  console.log('ranges', JSON.stringify(ranges))
  console.log(JSON.stringify(fields?.map((field) => ranges[field].indexOf(selectedDate[field].toString()))))

  TextPickerDialog.show({
    range: fields?.map((field) => ranges[field]) || [],
    selected: fields?.map((field) => ranges[field].indexOf(selectedDate[field].toString())) || [],
    canLoop: false,
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: 0 },
    disappearTextStyle: { color: $r("app.color.color_N7"), font: { size: 15, weight: FontWeight.Lighter } },
    textStyle: { color: $r("app.color.color_N7"), font: { size: 15, weight: FontWeight.Normal } },
    selectedTextStyle: { color: $r("app.color.color_B"), font: { size: 18, weight: FontWeight.Bolder } },
    acceptButtonStyle: {
      fontColor: pickerParams.rightBtn?.color || $r("app.color.color_W"),
      fontSize: '16fp',
      backgroundColor: $r("app.color.color_Switch_Select")
    },
    cancelButtonStyle: {
      fontColor: pickerParams.leftBtn?.color|| $r("app.color.color_B"),
      fontSize: '16fp',
      backgroundColor: $r("app.color.color_N4")
    },
    onAccept: (value: TextPickerResult) => {
      console.log(JSON.stringify(value))
      if(typeof value.value == 'string'){

      }else{
        value.value.forEach((item,index)=>{
          selectedDate[fields?.[index.toString()]] = item;
          updateRanges(fields?.[index.toString()], item);
        })
      }
      console.log('selectedDate:', JSON.stringify(selectedDate),formatSelectedDate(selectedDate, pickerParams.pattern))
      options.callback && options.callback(new Date(formatSelectedDate(selectedDate, pickerParams.pattern)).getTime()/1000)
    },
    onChange: (value:TextPickerResult)=>{
      fields?.forEach((field, index) => {
        updateRanges(field, value.value[index]);
      });
      ranges = getRanges(selectedDate, minDate, maxDate);
    }
  });

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
HarmonyOS
2025-01-09 14:45:41
442浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
Heiang

写了一个demo,修改demo里面的fruits,即可让弹窗中的内容也改变,demo如下:

@Entry
@Component
export struct TextPickerDialogExample {
  private select: number | number[] = 0
  // private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4', 'banana5'];
  private fruits: string[] = ['apple1', 'orange2', 'peach3', 'grape4', 'banana5','banana6','banana7']
  @State v:string = '';

  build() {
    NavDestination(){
      Row() {
        Column() {
          Button("TextPickerDialog:" + this.v)
            .margin(20)
            .onClick(() => {
              TextPickerDialog.show({
                range: this.fruits,
                selected: this.select,
                disappearTextStyle: {color: Color.Red, font: {size: 15, weight: FontWeight.Lighter}},
                textStyle: {color: Color.Black, font: {size: 20, weight: FontWeight.Normal}},
                selectedTextStyle: {color: Color.Blue, font: {size: 30, weight: FontWeight.Bolder}},
                onAccept: (value: TextPickerResult) => {
                  // 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项
                  this.select = value.index
                  console.log(this.select + '')
                  // 点击确定后,被选到的文本数据展示到页面
                  this.v = value.value as string
                  console.info("TextPickerDialog:onAccept()" + JSON.stringify(value))
                },
                onCancel: () => {
                  console.info("TextPickerDialog:onCancel()")
                },
                onChange: (value: TextPickerResult) => {
                  console.info("TextPickerDialog:onChange()" + JSON.stringify(value))
                },
                onDidAppear: () => {
                  console.info("TextPickerDialog:onDidAppear()")
                },
                onDidDisappear: () => {
                  console.info("TextPickerDialog:onDidDisappear()")
                },
                onWillAppear: () => {
                  console.info("TextPickerDialog:onWillAppear()")
                },
                onWillDisappear: () => {
                  console.info("TextPickerDialog:onWillDisappear()")
                }
              })
            })
        }.width('100%')
      }.height('100%')
    }

  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
分享
微博
QQ
微信
回复
2025-01-09 17:27:05


相关问题
如何修改WebuserAgent参数
895浏览 • 1回复 待解决
同意取消弹窗怎么实现?用哪个方法
5392浏览 • 1回复 待解决
如何理解自定义弹窗gridCount参数
3127浏览 • 1回复 待解决