🦋

PantaRhei 2~ Chip表示から選択結果の仮表示

2023/09/05に公開

数学の勉強なんて役に立たない?

余弦定理を暗記していることが実生活の役に立つか、といったら、立たないでしょうね。
プログラミングにおいても限定的でしょう。
でも数学の勉強(研究じゃなく、高校までの数学の話です)してよかったな、と思う。
個々の知識じゃなく、突破口の見つけ方、とか、解決手順、とか、そういう意味で。
勉強って、脳みそを耕す作業なので、
そこにどんな種をまいて何を収穫するか、以前の問題なんだと思う。

今回のこのニッチなルートを学んだ経験も、私の脳のよい肥料になると思う。

まずはChipを汎用化する

今回使うのはChoiceChip。一つしか選択できないヤツ。

class ChoiceFormat extends StatefulWidget {

  final List<String> choiceList;
  final String choiceKey;
  final int choiceValue;
  final Function(String) onChoiceSelected;

  const ChoiceFormat({super.key,

    required this.choiceList,
    required this.choiceKey,
    required this.choiceValue,
    required this.onChoiceSelected,
  });

  
  ChoiceFormatState createState() => ChoiceFormatState();
}

class ChoiceFormatState extends State<ChoiceFormat> {

  
  Widget build(BuildContext context) {
    return ChoiceChip(
        label: Text(widget.choiceKey),
        selected: widget.choiceList.contains(widget.choiceKey),
        selectedColor: Colors.yellow,
        onSelected: (bool value) {
          setState(() {
            if (value) {
              widget.choiceList.clear();
              widget.choiceList.add(widget.choiceKey);
            } else {
              widget.choiceList.removeWhere((filter) => filter == widget.choiceKey);
            }
          });
          widget.onChoiceSelected(widget.choiceKey); //ここが次に繋がる
        },
    );
  }
}

分岐に応じてChipを表示

               Wrap(
                spacing: 5.0,
                children: currentDisplayList.map<Widget>((item) {
                  if (item is Places) {
                    return ChoiceFormat(
                    choiceList: _filtersPlaces,
                    choiceKey: item.place,
                    choiceValue: item.id!,
                    onChoiceSelected: (choice) {
                      setState(() {
                        _chosenPlace = choice; //これを次に渡す。
                        print(_chosenPlace);
                      });
                    });
                } else if (item is Seas) {
                    return ChoiceFormat(
                        choiceList: _filtersSeas,
                        choiceKey: item.sea,
                        choiceValue: item.id!,
                       onChoiceSelected: (choice) {
                          setState(() {
                            _chosenSea = choice;
                          });
                      },
                    );
                  } else if (item is Countryatts) {
                    return ChoiceFormat(
                        choiceList: _filtersCountryatts,
                        choiceKey: item.countryatt,
                        choiceValue: item.id!,
                       onChoiceSelected: (choice) {
                        setState(() {
                          _chosenCatt = choice;
                        });
                      },
                    );
                  } else if (item is Placeatts) {
                    return ChoiceFormat(
                        choiceList: _filtersPlaceatts,
                        choiceKey: item.placeatt,
                        choiceValue: item.id!,
			onChoiceSelected: (choice) {
                          setState(() {
                            _chosenPatt = choice;
                          });
                      },
                    );
                  }
                  return const SizedBox.shrink();
                }).toList(),
              ),

今度の分岐はif文。
一回分岐したら、そのままダ〜っと行けないかしら、というのが悩みどころではある。
せっかくcurrentDisplayListで一元化したのに、また分けるのかい、みたいな。
ツッコミどころ満載かな。

仮表示って何。

さいしょ 'Current Place-name'でChipを表示して、一つ選ぶ。
で、実は、その後、別の選択肢に戻って、別のChipも選ぶ。

例えば
この前のPageで年表の必須項目、何年に、どこで(現在国名)、何が起こったか、を登録している。
ここでは、詳細情報を付加する。
例えば現在国名ロシアだとして、都市はサンクトペテルブルクです。
でも当時はソビエト連邦で、レニングラードと呼ばれていました。的な。

で、まずサンクトペテルブルクを選んだら、次は「当時の国名」に移りたいわけだけれど、
都市名で何選んだか消えちゃうのは問題でしょう。なので仮表示。

借り表示用空欄を下ごしらえ

TextFormFieldみたいに、ユーザーが書き込むための空欄ではない。
でもここに空欄があります、と、表示したい。
なので背景色がついている。そしてpointはpadding。
これがあることで、空欄が内容ゼロ文字でも潰れずに表示される。

class BlankTextFormat extends StatelessWidget {
  final String text;

  const BlankTextFormat({super.key, required this.text});

  
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Center(
        child: Container(
          padding: const EdgeInsets.fromLTRB( 24, 8, 24, 8),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(10),
            border: Border.all(color: Colors.white),
          ),
          child: Text(text, style: TextStyle(color: Colors.white)),
        ),
      ),
    );
  }
}

空欄をRadioButtonに並べる

このButtonで選択したのは、この言葉ですよ、とわかるように。

                  Expanded(
                    flex: 1,
                      child: Column(
                        children: [
                          BlankTextFormat(text: _chosenPlace),
                          BlankTextFormat(text: _chosenSea),
                          BlankTextFormat(text: _chosenCatt),
                          BlankTextFormat(text: _chosenPatt),
                        ],
                      )

Chipで何か選択されれば、自動的に文字列が入ってくる。
RadioButtonを選び直して、新しく検索し、新しいChipが選ばれれば、それも表示される。
なかなかよき、でしょ?

Chipの追加からデータ保存までは、次のお話

https://zenn.dev/flutteruniv_dev/articles/72d9728a40f402
https://zenn.dev/flutteruniv_dev/articles/7074d301505b4c
これは前のお話

Flutter大学

Discussion