Flutterを使ってみよう その10(入力操作①)

今回は、ボタンやテキスト入力やらの入力操作が必要なウィジェットの実装方法の知識を深めていきたいと思います。

環境

 ・MacOS Ventura 13.6.3
 ・Xcode 15.1
 ・VSCode 1.85.1
 ・Flutter 3.16.5
 ・Dart 3.2.3

1. 全体のコード例

今回は、外観がiOS風ウィジェットで、抜粋してます。

入力操作のウィジェットを説明するに当たり、ベースとなるサンプルコードを記載します。

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text(
          'Interactive',
        ),
      ),
      child: SafeArea(
        child: SingleChildScrollView(
          child: Container(
            width: double.infinity,
            color: Colors.grey,
            child: Container(
              padding: const EdgeInsets.all(15),
              child: const Column(
                children: [
                  TextFieldExample(), // テキスト入力
                  SwitchExample(), // スイッチ
                  SliderExample(), // スライダー
                  SegmentsExample(), // セグメント
                &nb

2. テキスト入力


テキスト入力は、 CupertinoTextField ウィジェットを使用します。

class TextFieldExample extends StatefulWidget {
  const TextFieldExample({super.key});

  @override
  State<TextFieldExample> createState() => _TextFieldExampleState();
}

class _TextFieldExampleState extends State<TextFieldExample> {
  late TextEditingController _text1Controller;
  late TextEditingController _text2Controller;
  late TextEditingController _text3Controller;

  @override
  void initState() {
    super.initState();
    _text1Controller = TextEditingController(text: 'text1');
    _text2Controller = TextEditingController(text: 'text2');
    _text3Controller = TextEditingController(text: 'multi1\nmulti2');
  }

  @override
  void dispose() {
    _text1Controller.dispose();
    _text2Controller.dispose();
    _text3Controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.topCenter,
      child: Container(
        color: Colors.blue,
        child: Padding(
          padding: const EdgeInsets.all(10),
          child: Column(
            children: [
              CupertinoTextField(
                controller: _text1Controller,
     &nb

3. スイッチ入力


スイッチ入力は、 CupertinoSwitch ウィジェットを使用します。

class SwitchExample extends StatefulWidget {
  const SwitchExample({super.key});

  @override
  State<SwitchExample> createState() => _SwitchExampleState();
}

class _SwitchExampleState extends State<SwitchExample> {
  bool switchValue = true;

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.topCenter,
      child: Container(
        color: Colors.white,
        child: Column(
          children: [
            Row(
              children: [
                const Text('スイッチ'),
                const Spacer(),
                CupertinoSwitch(
                  value: switchValue,
                  activeColor: CupertinoColors.activeGreen,
                  onChanged: (value) {
                    setState(() {
                      switchValue = value;
&nbs

4. スライダー入力


スライダー入力は、 CupertinoSlider ウィジェットを使用します。

class SliderExample extends StatefulWidget {
  const SliderExample({super.key});

  @override
  State<SliderExample> createState() => _SliderExampleState();
}

class _SliderExampleState extends State<SliderExample> {
  double _currentSliderValue = 0.0;
  String? _sliderStatus;

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.topCenter,
      child: Container(
        width: double.infinity,
        color: Colors.white,
        child: Column(
          children: [
            Text('スイッチ値 $_currentSliderValue'),
            SizedBox(
              width: double.infinity,
              child: CupertinoSlider(
                key: const Key('slider'),
                value: _currentSliderValue,
                divisions: 5,
                max: 100,
                activeColor: CupertinoColors.systemBlue,
                t

5. セグメント選択


セグメント選択は、 CupertinoSegmentedControl ウィジェットか、 CupertinoSlidingSegmentedControl ウィジェットを使用します。

CupertinoSegmentedControl ウィジェットは、外観が旧iOSイメージのセグメント選択になり、 CupertinoSlidingSegmentedControl ウィジェットは、外観が現iOSイメージのセグメント選択になります。

enum SegmentType { seg1, seg2, seg3 }

Map<SegmentType, Color> segmentTypes = <SegmentType, Color>{
  SegmentType.seg1: Colors.red,
  SegmentType.seg2: Colors.green,
  SegmentType.seg3: Colors.blue,
};

class SegmentsExample extends StatefulWidget {
  const SegmentsExample({super.key});

  @override
  State<SegmentsExample> createState() => _SegmentsExampleState();
}

class _SegmentsExampleState extends State<SegmentsExample> {
  SegmentType _selectedType = SegmentType.seg1;
  SegmentType _selectedSlidingType = SegmentType.seg2;

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.topCenter,
      child: Container(
        width: double.infinity,
        color: Colors.white,
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              child: CupertinoSegmentedControl<SegmentType>(
                selectedColor: CupertinoColors.activeBlue,
                groupValue: _selectedType,
 &n

6. ピッカー入力


ピッカー入力は、ある複数のデータから選択する場合は、 CupertinoPicker ウィジェット を、日時選択する場合は、 CupertinoDatePicker ウィジェット を使用します。

const List<String> _fruitNames = <String>[
  'Apple',
  'Mango',
  'Banana',
  'Orange',
  'Pineapple',
  'Strawberry',
];

class PickerExample extends StatefulWidget {
  const PickerExample({super.key});

  @override
  State<PickerExample> createState() => _PickerExampleState();
}

class _PickerExampleState extends State<PickerExample> {
  int _selectedFruit = 0;
  DateTime dateTime = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.topCenter,
      child: Container(
        width: double.infinity,
        color: Colors.white,
        child: Column(
          children: [
            SizedBox(
              height: 200,
              child: CupertinoPicker(
                itemExtent: 32,
                scrollController: FixedExtentScrollController(
                  initialItem: _selectedFruit,
                ),
          &

7. まとめ

今回は、入力操作が必要なウィジェットの実装方法を深めるのを目的に記事を書きました。

次回は、ポップアップ等の入力操作ウィジェットの実装方法に触れたいと思います。