つてとのブログ

【Dart/Flutter開発】表示制御と検索機能の実装、実際の(自作)アプリと考え方を共に...【スマホアプリ】

 

こんにちは、たちつてとです。

ゆるい収支管理アプリのベースができたので、

そこまでにどういう記述が必要だったかをまとめました。

ちなみに見た目に関しては、簡単にですが

【Flutter/Dart開発】見た目を整えるための基礎知識をまとめた【スマホアプリ】

でまとめました。

f:id:tachitutetoNosuke:20211003192324p:plain

一覧型の画面と登録型の画面を作ったのですが、まず一覧型の画面から。

 

画像の通り、日付とお金(出費)が対応した一覧画面になります。

画像の通り、機能は

  • ボタン押下で、表示/非表示になるエリアがある。
  • ボタン押下で、表示される日付のデータが変わる(検索)

になります。※データは、すでに登録してあるものです。

ちなみに、

画像上部の「2021年」や「10月」などをタップすると、

(ドロップダウンという要素)選択肢が表示されます。

 

本記事では、数字や日付などいわゆる「完全一致」の

絞り込みをしています。

以下記事では、検索バー的なものも実装してみました。

【Dart/Flutter開発】検索エンジンでありがちな、単語/言葉の検索機能(検索バー)を実装する、話

この記事では、「部分一致」、つまり

キーワードを「含む」検索になります。

 

【余談】

月ドロップダウンは、

タップすると1〜12月までの選択肢が表示されます。

あまりにも冗長だったので、

画面下部のボタンも実装しました。

 

 

順番に見ていきましょう!

 

ボタン押下時の表示制御

ここで必要なことは、二つです。

  • ボタンテキストの「+」/「ー」切り替え←発想の話
  • 該当エリアの表示制御←文法の話

まあ、知ってしまえばいずれも簡単な話なのです。

ボタンテキストの「+」/「ー」切り替え

日本語で書くと、

「ボタン押下時に該当ボタンのテキストを変える」です。

まあほぼそのまま...

→ボタンのテキストを変数にしちゃえって感じです。

 

はい、ソースです。

といっても該当部分だけ取ってきているのでチグハグですが...

細かい文法は割愛しまして、

作戦をお伝えできればと思います。

ListView.builder(
// リストを生成
itemBuilder: (context, index) {
Container(
child: SizedBox(
height: 50,
child: FloatingActionButton(
heroTag: "flt_open" + index.toString(),//heroTagは各ボタンでユニーク
onPressed: () {// ボタン押下時の処理
setState(() {// 一番大事な処理
if (isOpen == true) {
_openDetail[index] = false;
_buttonText[index] = '+';
} else {
_openDetail[index] = true;
_buttonText[index] = 'ー';
}
         
});
},
child: Text(_buttonText[index]),
)),
)

一覧を作るために、ListView.builderを使用しています。

細かい文法は割愛。

FloatingActionButtonというやつが、

「+」/「ー」ボタンの本体になります。

  • 「+」/「ー」表示用のList<String> _buttonText
  • 自身の開閉状態を記録するためのList<bool>_openDetail(後述)

をクラスのフィールドとして用意しています。

で、具体的な処理は、

OnPressの中にsetStateする

あとは機械的にbulidメソッドが呼び出され、

画面が変わります。

 

お次。

表示制御

こちらは、知識の話になります。

こちら

Visibility(
visible: isOpen,
child:

表示/非表示を切り替えたい要素を

Visibilityというのでラップし

(child以下に書き)ましょう。

isOpen = _openDetail[index]であり、

先述の通り

  • 自身の開閉状態を記録するためのList<bool>_openDetail

です。お分かりかと思いますが、

visible:true(=表示)、false(非表示)になります。

上述のOnPressでtrue/falseを切り替えることで、

「ボタン押下時に該当ボタンのテキストを変える」

を実現しています。

 

検索機能

こちらは、人によって書き方がまちまちになるかもしれません。

データをMap型の感じで保存するので、

keyと検索条件を比較して

(一覧をつくるための)

List型にaddするという方針です。

(僕は、「Hive」という

スマホのストレージに

データを保存する方針を取っています。)

 

ソース自体はあんまり参考にならない思いますが...

void loadData() async {
Hive.openBox<Mesai>(_mesai).then((value) {// 人によってまちまち
Box<Mesai> mesBox = value;
// List型をリセット
_dayMesai.clear();
_openDetail.clear();
_buttonText.clear();
   // List型を作り直し
for (Mesai mesai in mesBox.values) {// 変数など人によってまちまち
String date = mesai.dateNo.split('_')[0];//keyをいい感じに取り出す
if (date.split('/')[0] == _year &&
date.split('/')[1] == _month.padLeft(2, "0")) { // 検索条件を反映
_dayMesai.add(mesai);
_openDetail.add(false);
_buttonText.add('+');
}
}
  //以下も人によってまちまち
Container clm = getContainer();
asyncWidget = clm;

});
}

このloadDatamなるメソッドを、

ドロップダウンやボタンの変更/tapイベントに仕込んでいます。

大事なこと/考え・処理をまとめると、

  1. ボタン等のtapイベントで
  2. 検索条件用のフィールドに値を(setStateで)セット(_year=2021とか_month=6とか)
  3. loadData呼び出し(ここから↑ソース)
  4. List型をリセット
  5. forで検索条件を反映させつつ作り直し

しています。

 

以下は完全に僕専用の動きで、具体的には、

  1. date = 2021/08/01_1(=日付_連番)(=mapのkeyです)みたいな形式
  2. date.split('_')で日付と連番を分ける
  3. ↑配列[0]が日付に対応→その日付をsplit('/')でさらに年[0]と月[1]を取り出す
  4. 一方、今選択されている値(=2021年とか9月)と比較
  5. 該当するkeyの要素だけが、Listにaddされる

非効率かもしれませんが、完全に趣味の世界なので許して...?

 

ちなみに、

「まへ」とか「いま」とかいう(ふざけた)ボタンは、

1ヶ月移動するボタンです。

これも特別なことはなく、

「まへ」/「つぎ」ボタン:選択されている月プラマイ1

「いま」:DateTime.now()から年と月を取り出す

を検索条件用の(_yearとか_monthとか)変数に入れてるだけです。

まとめ

はい、まとめです。

要は、

  1. Visibilityで該当エリアをラップ
  2. ボタンテキストを変数化(=フィールド化)して、
  3. ボタンやドロップダウンのイベント時に(setState等で)セット

こんな感じになります(あっさりしすぎ?)。

 

javaの知識のみならず、

オブジェクト指向の知識を入れたい方は↓左の書籍。

javaDartは、特にクラス系統の記述で、

結構かぶっているところがあります。

自分もjavaのにわか知識に助けられました。

Dartを勉強したいぜ!な方は右の書籍。

購入から数週間後、右の本の後ろに

Dartの文法が載ってて唖然としました。

「初めから知ってれば、

ここまで苦労しなかったのでは...?」

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Javaのオブジェクト指向がゼッタイにわかる本[第2版] [ 立山秀利 ]
価格:2530円(税込、送料無料) (2021/9/26時点)

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Flutter モバイルアプリ開発バイブル [ 南里勇気 ]
価格:3509円(税込、送料無料) (2021/9/20時点)

エンジニア発オンラインスクール【RUNTEQ】