【Flutter】TextFormField 탭시에 피커(드럼 롤)를 내고 입력시킨다

양식을 만들 때 TextFormField
독자적인 위젯을 작성해도 좋지만, TextFormField 로서 구현하는 것으로, 다른 TextFormField 와 같이 onSave() 를 처리하거나 밸리데이션을 적응할 수가 있습니다.

'텍스트 필드를 탭하면 선택기(드럼 롤)가 표시되고 선택한 항목이 양식에 입력됩니다.'라는 것을 구현합니다.

먼저 일반 텍스트 필드를 만듭니다.

main.dart
TextFormField buildTextFormField(BuildContext context) {
    return TextFormField(
      decoration: const InputDecoration(hintText: 'テキストを入力'),
    );
  }
onTap() 에서 탭할 때 선택기를 호출합니다.
피커 부분의 구현은 이전의 투고를 참조.
【Flutter】화면 아래에서 나오는 피커(드럼 롤)를 실장한다

main.dart
TextFormField buildTextFormField(BuildContext context) {
  return TextFormField(
    onTap: () {
      // キーボードが出ないようにする
      FocusScope.of(context).requestFocus(new FocusNode());
      showPicker();
    },
    decoration: const InputDecoration(hintText: 'テキストを入力'),
  );
}

void showPicker() {
  final list = ['選択肢1', '選択肢2', '選択肢3'];
  final _pickerItems = list.map((item) => Text(item)).toList();
  var selectedIndex = 0;

  showCupertinoModalPopup<void>(
    context: context,
    builder: (BuildContext context) {
      return Container(
        height: 216,
        child: GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: CupertinoPicker(
            itemExtent: 32,
            children: _pickerItems,
            onSelectedItemChanged: (int index) {
              selectedIndex = index;
            },
          ),
        ),
      );
    },
  );
}


텍스트 필드를 탭하면 선택기가 시작됩니다.

그대로라면 피커가 나오기 전에 키보드가 일순간 표시되어 버리므로,FocusScope.of(context).requestFocus(new FocusNode()) 를 넣어 억제하고 있습니다.



선택기를 닫을 때 선택한 문자열을 TextFormField에 반영합니다.

main.dart
// コントローラーを追加
final TextEditingController _controller = TextEditingController();

TextFormField buildTextFormField(BuildContext context) {
    return TextFormField(
      onTap: () {
        // ...
      },
      // コントローラーを追加
      controller: _controller,
      decoration: const InputDecoration(hintText: 'テキストを入力'),
    );
  }

main.dart
showCupertinoModalPopup<void>(
  // ...
).then((_) {
  if (selectedIndex != null) {
    _controller.value = TextEditingValue(text: list[selectedIndex]);
  }
});



TextFormField 로서 구현하고 있기 (위해)때문에, validator()onSave() 를 구현할 수가 있습니다.

코드 전체

main.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TextFormField Picker',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(title: 'TextFormField Picker'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: buildTextFormField(context),
        ));
  }

  TextFormField buildTextFormField(BuildContext context) {
    return TextFormField(
      onTap: () {
        // キーボードが出ないようにする
        FocusScope.of(context).requestFocus(new FocusNode());
        showPicker();
      },
      controller: _controller,
      decoration: const InputDecoration(hintText: 'テキストを入力'),
    );
  }

  void showPicker() {
    final list = ['選択肢1', '選択肢2', '選択肢3'];
    final _pickerItems = list.map((item) => Text(item)).toList();
    var selectedIndex = 0;

    showCupertinoModalPopup<void>(
      context: context,
      builder: (BuildContext context) {
        return Container(
          height: 216,
          child: GestureDetector(
            onTap: () {
              Navigator.pop(context);
            },
            child: CupertinoPicker(
              itemExtent: 32,
              children: _pickerItems,
              onSelectedItemChanged: (int index) {
                selectedIndex = index;
              },
            ),
          ),
        );
      },
    ).then((_) {
      if (selectedIndex != null) {
        _controller.value = TextEditingValue(text: list[selectedIndex]);
      }
    });
  }
}

좋은 웹페이지 즐겨찾기