見出し画像

タブでのカテゴリ分け -ひとりアドベントカレンダー Flutter編 2018 その12-

MaterialIconは数が豊富で良いのですが、フラットなままで見ると数が多すぎて少し見づらいです。
ということで、12日目はアイコンをタブでカテゴリ分けしてみます。

昨日までの内容と今後については目次を参照してください。

ところで、JSONデータを処理するときに利用したAPIにはカテゴリ情報がついていました。
今回はそのカテゴリ情報を元にしてタブに分割表示してみます。

いつもどおりGitHubのプロジェクトChapter12でブランチを作ってます。今回は変更点が大きいので、3つに対応を分けて進めます。
全てのソースは載せれないので、ぜひDiff表示で見てみてください。

モデルの調整
まずは作成したIconモデルにカテゴリ情報を追加してみましょう。

class MIcon {
  String key;
  int codepoint;
  IconData iconData;
  String category;

  MIcon({
    @required this.key,
    @required this.codepoint,
    @required this.iconData,
    this.category = "",
  });
}

モデルはこんな感じで、以前のMIconにカテゴリーを追加しただけです。

List<MIcon>なMIconsの実装はここを参照ください。少し長いですが、やってることは理解できると思います。

データ取得方法の調整
この調整についても変更点が大きいので、ここを参照ください。

少し解説すると、
1. StatelessWidgetからStatefulWidgetへ変更
2. FutureBuilderを使わずにinitStateでIconを取得
3. ScaffoldをDefaultTabControllerでラップ
4. AppBarのbottomにTabBarが追加
というところが大きな変更点です。

1.のStatefulWidgetはFlutterでも大きな特徴になっていますので、ここでの説明は不要だと思います。
2. についてはカテゴリの一覧とアイコンの一覧を準備する必要があるので、FutureBuilderではなくinitStateを利用したsetStateで値を作ってます。
3.と4.はタブ表示のための準備です。タブのタップで表示内容を切り替えるためにはコントローラーがなるべく上にあったほうが下流の状態を操作しやすいと思うので、妥当なところでしょう。

処理の流れ的には、
1. initStateでIconの一覧とCategoryの一覧を非同期で取得開始
2. アイコン一覧が取得されるまではインジケーター表示
3. アイコン一覧の取得が完了したらsetStateでWidgetを再描画
4. appBarに指定するカテゴリは横スクロール(isScrollable: true)付きとし、List.generateでリストを作成(mapでも良さそう)。
5. bodyに指定するTabBarViewもまたList.generateでcategory別にGridVIewを作成する(表示させるアイコンは表示しているカテゴリの番号を元にwhereでフィルタリングする。

以上の対応でこんな感じになります。

noteではソースを貼り付けながら説明しにくくこんな説明になってしまい、十分な説明ができてない感じもしますが、今回はこれで一応終わりです。

ポイントとしては「モデル側でIcon一覧とCategory一覧を別に用意する」というところと、「ビュー側では非同期にIcon一覧とCategory一覧を参照してそれぞれ必要に応じてTabコントローラーに渡す」という感じです。

・・・

今回の内容はnoteで説明するにはちょっと難しかったな。Gistの埋め込みに対応してくれれば最高なんだけど。
コメントまたはTwitterで質問受け付けてます。


趣味のプログラミングにもいろいろとお金がかかって大変なんですわ。特に小遣い制の妻帯者は。