👨‍👩‍👦‍👦

checkした人だけListに入れて、次のページに渡す

2024/03/15に公開

これは何か?

副業の案件で、checkboxでチェックした人だけを次のページに表示する要件があった。どうすればできるんだろうって考えた。
「う〜ん難しいぞ(^^;;」ものは試しでやってみたらできたから似たような機能をサンプルで作ってみました。

⭐️必要だったもの

DartのListとコンストラクーの知識。オブジェクト指向の知識といった方がいいかもしれない。

まずはViewで使うモデルを作る。これはAPIのJSONの構造に合わせなくて良い。だって、DBの方には、bool型の変数だけないですもん笑
あるのは、bool型以外のプロパティだけですね。bool型のプロパティはView側でcheckboxでだけ使います。

値を受け取るページと渡すページの両方で使うエンティティです。ただの入れもんですね。

class UserInvitation {
  UserInvitation({required this.userName, required this.isInvited});
  String userName;
  bool isInvited;
}

値を受け取るページ。ここにはList型でコンストラクターに値を渡してあげないといけません。渡すのは複数のオブジェクト。クラスの型を指定しただけだと、単一のオブジェクトを渡すだけなので、List<クラス名>で渡す必要がありました。単一のオブジェクト渡すとエラー出ます!!!

import 'package:flutter/material.dart';
import 'package:widget_cookbook/invitation/invitation_user.dart';

class InvitationPage extends StatefulWidget {
  const InvitationPage({super.key, required this.userInvitation});

  final List<UserInvitation> userInvitation;

  
  State<InvitationPage> createState() => _InvitationPageState();
}

class _InvitationPageState extends State<InvitationPage> {
  
  Widget build(BuildContext context) {
    return  Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.green[400],
        title: const Text('招待ユーザするー一覧'),
      ),
      body: ListView.builder(
        itemCount: widget.userInvitation.length,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text(widget.userInvitation[index].userName),
          );
        },
      ),
    );
  }
}

こちらが値を渡すページ。ダミーのデータが入ったListのデータをメソッドを使って、Listに代入して次のページで渡しています。APIを使ったときは、mapメソッドを使ったのですが、今回はダミーのデータをfor文でループして、次のページに渡すListに代入しています。
メソッドを実行する必要があるので、initStateでページが呼ばれたら実行しています。

import 'package:flutter/material.dart';
import 'package:widget_cookbook/invitation/invitation_page.dart';
import 'package:widget_cookbook/invitation/invitation_user.dart';

class InvitationView extends StatefulWidget {
  const InvitationView({super.key});

  
  State<InvitationView> createState() => _InvitationViewState();
}

class _InvitationViewState extends State<InvitationView> {
  // dummy data
  List<String> persons = ['田中太郎', '山田花子', '佐藤次郎'];
  // user list
  List<UserInvitation> invitationUser = [];

  void fetchUser() {
    for (var person in persons) {
      invitationUser.add(UserInvitation(userName: person, isInvited: false));
    }
  }

  
  void initState() {
    fetchUser();
    super.initState();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => InvitationPage(
                    userInvitation: invitationUser.where((element) => element.isInvited).toList(),
                  ),
                ),
              );
            },
            icon: const Icon(Icons.arrow_forward),
          ),
        ],
        backgroundColor: Colors.green[400],
        title: const Text('ユーザー一覧'),
      ),
      body: ListView.builder(
        itemCount: invitationUser.length,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text(invitationUser[index].userName),
            trailing: Checkbox(
              value: invitationUser[index].isInvited,
              onChanged: (bool? value) {
                setState(() {
                  invitationUser[index].isInvited = value!;
                });
              },
            ),
          );
        },
      ),
    );
  }
}

選択したユーザーだけ表示してみる

チェックしてない場合だと表示されません!

1個だけチェックした場合

最後に

今回は、招待機能なるものを作りたかったのですが、どうやるのかって考えていたときに、まずは招待する人を選ぶ機能がいるだろうってことで、今回のような機能を作ってみました。
必要なのは、オブジェクト指向の知識でしたね。if, for, switchなどなど。基本的な文法だけでできることは多いことを最近知って、探求してます。

Discussion