こんにちはEveryDaySoft代表の永田です。
今回はFlutter、Dart言語で夜中の24時を00ではなく、24時に表示する方法を紹介します。
ソースコード
https://github.com/daisukenagata/custom24_picker
挙動
モデルとしたソース デフォルトのCupertinoPicker
iOSスタイルのピッカーです。
https://api.flutter.dev/flutter/cupertino/CupertinoPicker-class.html
こちらのソースを選択した理由は、ネット上で画像を検索したところ
24表記のような情報はなく、
番号専用のピッカーですと、開発者公開しているPackageが多かったです。
なので、Flutterから公開しているソースコードを改造するのが一番良いかなと思いました。
デフォルトのCupertinoPickerの場合 単体のWidgetしか設定できない作りになっていました。



ソースコード全体を眺めてみると、継承しているクラスが少なく、依存関係が比較的少ない構成になっていたので、丸ごとコピーして、必要箇所を修正すれば実装可能だなと軽く考えました。
ですが、単純にListにして値を渡すだけでは上手くいきません。
難しかったポイント
CupertinoPicker.builderのrequired NullableIndexedWidgetBuilder itemBuilder itemBuilderです。
itemBuilderはListViewでも良く使用しているパラメーターですね。
body: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Container();
},
)
itemBuilder設定を複数デリゲードしなくてはいけませんが、itemBuilderの型はスーパークラスを確認すると、
この機能ですが、これを初期化、デリゲードする方法は情報がありませんでした。

実施したいことはピッカーの表示情報ごとにitemBuilderに携わるListWheelChildLoopingListDelegate及びListWheelChildListDelegateをデータごとに初期化、childDelegateも初期化することです。
デフォルト画像


クラス宣言と同時にsuper.initState()よりも速い段階で初期化してますが、Listで初期化する方法が見当たりませんでした。
対応した方法
childDelegateを?やlateにするとnullになり値が代入できないので、required this.childDelegateにする必要がありました。ということは使用箇所でchildDelegateの型を設定する必要がありますが、そちらは後に説明します。
実装画像

クラスの最初の呼び出しは{ }このブロック内は実行されます。使用側で初期化設定しているので、エクセプションにはなりません。
Custom24Picker.builderは{}のブロック内は実行されません。この書き方で実行されます。childDelegate自体は一つのデータ設定で上手く機能しました。ListWheelChildBuilderDelegateが一つの設定だけで良いのはbindする設定の解釈です
実装画像

childDelegateを使用側で設定する方法
childDelegateを呼び出し元の_MyHomePageState Classで実装しています。_listなどのメソッドは表示データのメソッドです。TODOと記載している箇所は設定箇所、ポイントとなるコード箇所です。

childDelegateはこのように宣言しています。
final List<ListWheelChildDelegate> childDelegate;
この宣言によりwidgetデータを複数デリゲートすることができました。
FixedExtentScrollControllerもListで設定していることにより、どのスクロールは認識できるので、bindは共通ですが、アクションしているスクロールを認識し表示分岐に使用しています。
実装画像
indexの値に選択されたFixedExtentScrollControllerの要素番号を付与しています。

実装画像
使用側で受け取った値です。スクロール箇所ごとに値を代入するようにしています。

ざっくりですが、ポイントとなる箇所を記載しました。あと何工程かありますが、TODOと記載している箇所などを確認するとソースコードがわかる人はわかると思いますし、答えが分かれば、影響範囲の少ない簡単なソースコードです。
貴重なお時間お読みくださいまして、誠にありがとうございます。
コメントを残す