[読書会]新しい画面にデータを送信する

 新しい画面移動するだけでなく、その画面にデータを渡したいこともよくあります。
(例えば、タップされた項目に関する情報を渡したい場合があります。)

1.Todo クラスの定義

 まず、Todo クラス(メンバ: タイトル、詳細データ)を作成します。

まず、Todo クラス(メンバ: タイトル、詳細データ)を作成します(例):
class Todo {
  final String title;
  final String description;

  const Todo(this.title, this.description);
}

2.Todo リストの作成

 次に、Todo リスト(データ件数:20(固定))を作成します。

次に、Todo リスト(データ件数:20(固定))を作成します(例):
final todos = List.generate(
  20,
  (i) => Todo(
    'Todo $i',
    'A description of what needs to be done for Todo $i',
  ),
);

 そして、上記の Todo リスト を、ListView により、リスト表示します。

そして上記の Todo リスト を、ListView により、リスト表示します(例):
ListView.builder(
  itemCount: todos.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(todos[index].title),
    );
  },
)

3.リスト表示用 Todo 画面の作成

 上記実装の為に、StatelessWidget (ここでは以下コード中の TodosScreen )を作成します。

・(このページ内容は実行時に変更されない為)ウィジェットのスコープ内で Todo のリストを要求する必要があります。
build() body ListView.builder を渡します。

 これでリストが画面にレンダリングされ、実行できるようになります。

上記実装の為に StatelessWidget (ここでは以下コード中の TodosScreen )を作成します。
class TodosScreen extends StatelessWidget {
  //Todos リストをコンストラクタで渡す。
  const TodosScreen({super.key, required this.todos});

  final List<Todo> todos;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Todos'),
      ),
      //Todos をリスト表示する。
      //( build() に返すウィジェットの body に ListView.builder を渡します )
      body: ListView.builder(
        itemCount: todos.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(todos[index].title),
          );
        },
      ),
    );
  }
}

4.Todo関連情報表示用詳細画面の作成

 ここでは「Todo」の詳細情報を表示する画面の作成について触れています。

(1)DetailScreenクラスの作成

 まず、StatelessWidget クラス( 以下の DetailScreen )を作成します。
このクラスの目的は、渡された「Todo」オブジェクトの詳細情報(タイトルと説明)を表示することです。
詳細画面は、新しい画面として表示され、具体的な情報はユーザが選択した「Todo」から受け取ります。

具体的な情報はユーザが選択した「Todo」から受け取ります。
class DetailScreen extends StatelessWidget {
  //コンストラクタでTodoオブジェクトを受け取ります。
  const DetailScreen({super.key, required this.todo});

  //Todoオブジェクトを保持するフィールドを宣言。
  final Todo todo;

(2)コンストラクタでTodoオブジェクトを渡す

 DetailScreen のコンストラクタでは、required を使用して Todo オブジェクトを受け取ります。このオブジェクトには「Todo」のタイトルや説明が格納されています。

(3)UIの構築

 build メソッドでUIを作成します。以下の要素を構成しています。

  • AppBar
     上部には「Todo」のタイトルが表示されます。
     これは todo.title を使用して動的に設定されます
  • Padding
     コンテンツを画面の端から一定の距離に配置する為にパディングを使用します。
  • Textウィジェット
     todo.description に基づいて、「Todo」の説明が表示されます
Dart
  @override
  Widget build(BuildContext context) {
    //Todoオブジェクトを使ってUIを作成します。
    return Scaffold(
      appBar: AppBar(
        title: Text(todo.title),  //Todoのタイトルを表示
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),  //16pxの余白を追加
        child: Text(todo.description),  //Todoの説明を表示
      ),
    );
  }
}
  • Todoオブジェクト
     この DetailScreen では Todo オブジェクトを受け取り、そのオブジェクトのタイトルと説明を表示します。
  • シンプルな画面構成
     基本的に AppBar と Text ウィジェットを組み合わせ、シンプルに情報を表示します。
     Padding で適切な余白を確保することで、視覚的に見やすくしています。

5.詳細画面に移動してデータを渡す

 リスト内の項目(todo)をタップすると詳細画面(DetailScreen)に遷移し、選択した項目のデータをその画面に渡す手順です。

(1)ユーザーのタップを検出する

 TodosScreenでリスト項目をタップした際詳細画面に遷移する様に、ListTile ウィジェット onTap コールバックを使用します。
ここで、タップされた項目に対応する todo データを DetailScreen に渡します。

タップされた項目に対応する todo データを DetailScreen に渡します。
body: ListView.builder(
  itemCount: todos.length,  //リストの項目数
  itemBuilder: (context, index) {
    return ListTile(
      //各項目のタイトルを表示
      title: Text(todos[index].title),
      //ListTile タップ時 DetailScreen に遷移する
      onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(
            //DetailScreenに todo オブジェクトを渡す
            builder: (context) => DetailScreen(todo: todos[index]),
          ),
        );
      },
    );
  },
),

(2)Navigator.push() メソッドの利用

 タップされた際に、Navigator.push() を呼び出して( DetailScreen に )遷移します。
(ここで、新しいルート(画面)をスタックに積むことで遷移が行われます。
このメソッドの builder パラメータで、DetailScreen を作成し、todo データを渡しています。)

  • Navigator.push
     新しい画面現在の画面上に積むメソッドです。
     (ここでは、詳細画面が表示されます。)
  • MaterialPageRoute
     このオブジェクトを使用して、画面遷移時アニメーション等を定義します。
     (タップされた todo オブジェクト 遷移先(DetailScreen) に渡されます。)

コメントを残す