[開発者日記] タスクメモアプリ開発 11日目

本日はUIを作成して、タスクを追加・削除をできるようにします。

構成するUI

今回構成する画面は、タスクをリストとして表示して、追加ボタンを表示リストの一番下に配置します。また、削除するときはスライド削除で実行できるようにします。
※今回はタスクを追加するのみのため、タスクを入力・編集処理は省きます。

イメージはこんな感じです。

なんちゃってUI設計図

データを表示・削除可能なListを作成する

まずタスクを表示するListを作成していきます。
表示できてスワイプすると削除してくれる機能があるListを作成する方法ですが、公式に載っていました(やったね)。

データを表示する部分(ListView.Builder)

データを表示する部分はListView.Builderを使用して構築します。
ListView.builderは、

The standard ListView constructor works well for small lists. To work with lists that contain a large number of items, it’s best to use the ListView.builder constructor.
# 訳
標準の ListView コンストラクターは、小さなリストに適しています。 多数の項目を含むリストを操作するには、ListView.builder コンストラクターを使用することをお勧めします。

Flutter公式より

ということなので単純なデータ表示ViewはListView.builderを使用したら良さそうですね。単純なListView.builderの引数は、

ListView.builder(
  itemCount: アイテム数,
  prototypeItem: 計算効率のために使用するウィジェット,
  itemBuilder: 表示するウィジェットを返すコールバック関数
  },
)

で構成されています。私は引数のitemCountprototypeItemの使用方法は理解できたのですがitemBuilderの使い方を理解できませんでした。

itemBuilderはどうやって使うのか

ListViewの使い方として、

ListView.builder(
  itemCount: items.lenth,
#↓↓↓ここに注目
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(items[index]),
    );
  },
)

こんな形で使用していました。itemBuilderにcontextとindexを引数としたコールバック関数を使用してListTileウィジェットを返しています。indexは表示するリストのインデックスを示していますが、contextの意味合いが理解できませんでした。時間があるときにでもcontextを調べて記事にしたいと思います。

Listのスワイプ部分

データを削除するときはスワイプで削除できるようにしていきます。
Listのスワイプ部分は、Dismissible widgetで構築します。

DBからデータを取得・削除する機能を追加

DBからデータを表示・削除する機能を追加します。

表示機能部分

プロバイダクラスをインスタンス生成して対称テーブルのアイテムをすべて取り出すようにします。

Future refreshTasks() async {
    List<Task> tasks = await TaskProvider.instance.getAllTasks();
    items = tasks;
  }

削除機能部分

削除部分は先程のDissmissible WidgetのonDissmissのコールバック関数内で記述します。テーブルからデータを削除して、対称テーブルからすべてのデータを取り出すようにしています。

// アイテム表示部分
body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          final item = items[index];
          return Dismissible(
            key: Key(item.id.toString()),

            onDismissed: (direction) {
              
              deleteTask(item.id!);
              refreshTasks();
              
            },
            // Show a red background as the item is swiped away.
            background: Container(color: Colors.red),
            child: ListTile(
              title: Text(item.task),
            ),
          );
        },
      ),

// 省略

// 取得関数
Future refreshTasks() async {
  List<Task> tasks = await TaskProvider.instance.getAllTasks();
  items = tasks;
}

// 削除関数
Future deleteTask(int id) async {
  await TaskProvider.instance.delete(id);
}

表示データが更新されない

よし!実装したので動作確認しようとしましたが、表示データが更新されない不具合が見つかりました。

原因を調べてみるとテーブルから取得した値をState更新していないことが原因でした。そのため、更新時にsetStateの引数であるコールバック関数内で表示するitem変数を更新する必要があります。

Future refreshTasks() async {
   List<Task> tasks = await TaskProvider.instance.getAllTasks();
// 修正箇所(setStateを追加) 
    setState(() {
     items = tasks;
   });
 }

完成

アイテムを追加したら、追加されたアイテムが無事にリストに表示できることが確認できました☺

実装画面

まとめ・次回やること

今回はリストにアイテムを表示・削除を行いました。
次回はアイテムを入力してからリストを作成したりエディタ機能を構築したいと思います。

ではでは!


参考URL


この記事が気に入ったらサポートをしてみませんか?