FormField와 FormFieldState를 상속하여 자체 입력 필드를 만드는 방법

13159 단어 DartFlutter

세 줄로


  • 여기서 "자신 입력 필드"는 입력 필드를 탭하면 선택기 또는 모달과 같은 간단한 키보드 문자 입력이 아닌 방식으로 값을 입력 할 수있는 필드를 나타냅니다
  • .
  • 이번에는 모달 표시한 영역에 TextField를 두고 iOS풍의 입력을 할 수 있는 샘플을 예로 설명합니다
  • 상속의 부모 클래스 ( FormField , FormFieldState )의 메소드를 활용하면 폼의 구현이 편해지기 때문에 좋았습니다

  • 자체 입력 필드의 예


  • htps : // 기주 b. 코 m / 마사시 스토 / 쿠 s와 m_ 후 rm_ 후에 ld



  • 표시

    탭시

    값 입력

    입력 완료








    구현 포인트



    1. FormField 빌더에서 입력 필드 조립


  • FormField에서 builder에 입력된 값을 표시하는 방법을 조립합니다.
  • 샘플은 InputDecorator로 표시됩니다.

  • custom_form_field.dart#L27-L46
    builder: (FormFieldState<String> field) {
      final effectiveDecoration = decoration.applyDefaults(
        Theme.of(field.context).inputDecorationTheme,
      );
    
      return InputDecorator(
        decoration: effectiveDecoration.copyWith(
          errorText: field.errorText,
        ),
        isEmpty: value?.isEmpty ?? true,
        child: Padding(
          padding: const EdgeInsets.only(right: 6),
          child: Text(
            value ?? '',
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
          ),
        ),
      );
    },
    

    2. FormFieldState의 build에서 부모 클래스의 super.build를 호출하고 GestureDetector에서 탭을 감지합니다.


  • 입력 전용의 Widget은 탭 이벤트로 표시하고 싶기 때문에, 편의적으로 부모 클래스의 super.build(context)를 건네줍니다

  • custom_form_field.dart # L67-L74
    @override
    Widget build(BuildContext context) {
      return GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () => _handleTap(context),
        child: super.build(context),
      );
    }
    

    3. FormFieldState에서 탭한 후 입력 필드를 조립합니다.


  • 2. GestureDetectoronTap에 반응하여 표시 할 자체 입력 필드를 조립합니다
  • .
  • 샘플 프로젝트에서는 showModalBottomSheet에서 iOS 스타일의 반모달 입력 영역을 표현하고 거기에 입력 전용 TextField을 배치했습니다.

    custom_form_field.dart # L76-L99
    void _handleTap(BuildContext context) {
      FocusScope.of(context).unfocus();
      final initText = widget.initialValue ?? '';
      _textChangedNotifier.value = initText;
      _textController.text = initText;
    
      showModalBottomSheet<String>(
        context: context,
        isScrollControlled: true,
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(32),
            topRight: Radius.circular(32),
          ),
        ),
        builder: _textFieldModalSheet,
      ).whenComplete(() {
        // NOTE: 完了するボタンを押さずに選択画面を閉じた場合は選択前に戻す
        if (!_isTapDoneButton) {
          super.reset();
          super.save();
        }
      });
    }
    

    4. FormFieldState 상태 관리 메소드를 사용하여 입력 값을 제어합니다.


  • FormFieldState에는 입력 값의 상태를 제어하는 ​​몇 가지 메소드가 있습니다
  • .
  • 아래의 메소드를 입력 값을 설정하고 싶을 때, 리셋하고 싶을 때, 저장하고 싶을 때 호출합시다.
  • super.setValue (T value)
  • super.reset()
  • Sper. 사베()

  • 아래 코드는 완료 버튼을 눌렀을 때의 처리입니다

  • custom_form_field.dart#L123-L147
    ValueListenableBuilder<String>(
      valueListenable: _textChangedNotifier,
      builder: (context, editingText, __) {
        final enableDoneButton =
            editingText.characters.length <= widget.maxLength;
        return FlatButton(
          textTheme: ButtonTextTheme.primary,
          child: Text(
            '完了する',
            style: TextStyle(
              fontWeight: enableDoneButton
                  ? FontWeight.bold
                  : FontWeight.normal,
            ),
          ),
          onPressed: enableDoneButton
              ? () {
                  _isTapDoneButton = true;
                  super.setValue(editingText);
                  super.save();
                  FocusScope.of(context).unfocus();
                  Navigator.pop(context);
                }
              : null,
        );
      },
    

    참고


  • htps : // 아피. fぅ r. 에서 v / f ぅ는 r / 우드 드 ts / 후 rm 푸에 ldc ぁ s. HTML
  • htps : // 아피. fぅ r. 에서 v / f ぅ는 r / 우드 드 ts / 후 rm 푹 ldS 갓 - c ぁ s. HTML
  • 좋은 웹페이지 즐겨찾기