Custom24_Picker

こんにちは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と記載している箇所などを確認するとソースコードがわかる人はわかると思いますし、答えが分かれば、影響範囲の少ない簡単なソースコードです。

貴重なお時間お読みくださいまして、誠にありがとうございます。