由于state.didChange()调用而在Forms中使用时,缓慢的Cupertino输入字段

时间:2019-01-16 02:21:50

标签: dart flutter

由于在FormField中使用选取器并在选取器的formFieldState.didChange()上调用onDateTimeChanged,每当CupertinoDatePicker旋转时,UI口吃

我正在尝试在我的应用中使用Cupertino输入字段。 我已按照Flutter Gallery中的步骤使用CupertinoDatePicker。但是,我将输入字段包装在Form中以进行验证。

这有效,因为我能够将选择器的状态绑定到FormFieldState。但是,UI性能很差。每次旋转选择器时,都会遇到断断续续的情况。这是由于在state.didChange()上不断调用onDateTimeChanged

仅在消除模式弹出框后,我才尝试致电state.didChange(),它消除了结结巴巴的情况。但是我希望FormField的状态在用户旋转选择器时更新。

这是我的代码段。

  Widget _getCupertinoDateTimeFormField(FormFieldState<DateTime> state) {
    return GestureDetector(
      onTap: () async {
        await showCupertinoModalPopup<void>(
            context: state.context,
            builder: (BuildContext context) {
              return _buildBottomPicker(
                  CupertinoDatePicker(
                    mode: CupertinoDatePickerMode.date,
                    initialDateTime: state.value?? DateTime.now(),
                    onDateTimeChanged: (DateTime newDateTime) {
                      state.didChange(newDateTime);
                    },
                  )
              );
            },

        );
      },
      child: cupertinoDecoration(state, description,
        Text(
          _formatUI(state.value),
          style: const TextStyle(color: CupertinoColors.inactiveGray),
        ),
      ),
    );
  }

  Widget _buildBottomPicker(Widget picker) {
    return Container(
      height: _kPickerSheetHeight,
      padding: const EdgeInsets.only(top: 6.0),
      color: CupertinoColors.white,
      child: DefaultTextStyle(
        style: const TextStyle(
          color: CupertinoColors.black,
          fontSize: 22.0,
        ),
        child: GestureDetector(
          // Blocks taps from propagating to the modal sheet and popping.
          onTap: () {},
          child: SafeArea(
            top: false,
            child: picker,
          ),
        ),
      ),
    );
  }

Widget cupertinoDecoration <T> (FormFieldState<T> state, String description, Widget field) {
  bool isError = state.errorText != null;
  Widget label = Padding(
    padding: EdgeInsets.symmetric(vertical: 1.0),
    child: Text(
      description,
      maxLines: 1,
      overflow: TextOverflow.ellipsis,
      style: TextStyle(
        fontSize: 14.0,
        color: CupertinoColors.black,
      ),
    ),
  );

  List<Widget> fieldWidgets = [label, field];
  if (isError) {
    // add our error message
    fieldWidgets.add(Text(
      state.errorText,
      maxLines: 1,
      overflow: TextOverflow.ellipsis,
      style: const TextStyle(
        color: CupertinoColors.destructiveRed,
        fontSize: 12.0,
      ),
    ));
  }

  return Container(
    decoration: const BoxDecoration(
      color: CupertinoColors.white,
      border: Border(
        bottom: BorderSide(
            color: CupertinoColors.inactiveGray, width: 0.0),
      ),
    ),
    child: Padding(
      padding:
      const EdgeInsets.all(6.0),
      child: SafeArea(
        top: false,
        bottom: false,
        child: DefaultTextStyle(
          style: const TextStyle(
            letterSpacing: -0.24,
            fontSize: 17.0,
            color: CupertinoColors.black,
          ),
          child: Align(
            alignment: Alignment.centerLeft,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: fieldWidgets,
            ),
          ),
        ),
      ),
    ),
  );
}

我在这里很不幸吗?我们不应该将选择器的状态链接到FormField的状态吗?

提前谢谢!

0 个答案:

没有答案