2
  List<User> allusers = [];
  List<User> selectedUsers = [];
  List<User> selectableUsers = allusers - selectedUsers

Is anyone able to help me how to get selectableUsers list here? I am trying to subtract the selected users from all users so that the search function eliminates selectedUsers?

I want to filter users based on the selection.

View for getting and searching users. Issue is that selected user gets into the search once again. Expected behavior is that "selected" users shouldn't come up in the "selectable" user list.

class SearchGroup extends StatefulWidget {
  const SearchGroup({Key? key}) : super(key: key);

  @override
  State<SearchGroup> createState() => _SearchGroupState();
}

class _SearchGroupState extends State<SearchGroup> {
  final TextEditingController _searchController = TextEditingController();

  List<User> _users = [];
  List<User> _selectedUsers = [];
  List<User> _selectableUsers = [];

  @override
  void initState() {
    super.initState();
    var setAllUsers = Set.from(_users);
    var setSelectedUsers = Set.from(_selectedUsers);
    _selectableUsers
        .addAll(List.from(setAllUsers.difference(setSelectedUsers)));
  }

  _clearSearch() {
    WidgetsBinding.instance
        .addPostFrameCallback((_) => _searchController.clear());
    setState(() => _selectableUsers = []);
  }

  @override
  void dispose() {
    super.dispose();
    _searchController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final currentUserUid =
        Provider.of<UserProvider>(context).getUser?.uid ?? '';
    return Scaffold(
      appBar: AppBar(
        title: TextField(
            controller: _searchController,
              hintText: 'Search & select users by fullname',
              suffixIcon: _selectableUsers.isEmpty
                  ? Icon(Icons.search,
                      size: 20.0, color: Color.fromARGB(255, 235, 228, 228))
                  : IconButton(
                      iconSize: 15,
                      icon: Icon(CupertinoIcons.clear_circled_solid),
                      onPressed: _clearSearch,
                      color: Color.fromARGB(255, 235, 228, 228)),
            ),
            onSubmitted: (input) async {
              if (input.trim().isNotEmpty) {
                List<User> users =
                    await Provider.of<DatabaseService>(context, listen: false)
                        .searchUsers(currentUserUid, input);

                _selectedUsers.forEach((user) => users.remove(user));
                _selectableUsers.forEach((user) => users.remove(user));

                setState(() {
                  _selectableUsers = users;
                });
              }
            }),
    
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 5.0),
            child: Container(
              width: double.infinity,
              height: 100,
              child: ListView.builder(
                  itemCount: _selectedUsers.length,
                  scrollDirection: Axis.horizontal,
                  itemBuilder: (BuildContext context, int index) {
                    User selectedUser = _selectedUsers[index];
                    return Container(
                      margin: EdgeInsets.all(10),
                      width: 60,
                      height: 60,
                      decoration: BoxDecoration(shape: BoxShape.circle),
                      child: GestureDetector(
                        onTap: () {
                          _selectedUsers.remove(selectedUser);
                          _selectableUsers.insert(0, selectedUser);
                          setState(() {});
                        },
                        child: Stack(
                          alignment: AlignmentDirectional.bottomEnd,
                          children: [
                            CircleAvatar(
                              radius: 60,
                              child: CachedNetworkImage(
                                imageUrl: selectedUser.profileImageUrl,
                                imageBuilder: (context, imageProvider) =>
                                    Container(
                                  height: 60,
                                  width: 60,
                                  decoration: BoxDecoration(
                                    borderRadius:
                                        BorderRadius.all(Radius.circular(100)),
                                    image: DecorationImage(
                                      image: imageProvider,
                                      fit: BoxFit.cover,
                                    ),
                                  ),
                                ),
                              ),
                            ),
                            Positioned(
                              top: 3,
                              child: Icon(
                                Icons.remove_circle,
                                size: 20,
                                color: Colors.red,
                              ),
                            ),
                          ],
                        ),
                      ),
                    );
                  }),
            ),
          ),
          Expanded(
            child: ListView.separated(
              separatorBuilder: (BuildContext context, int index) {
                return const Divider(thickness: 1.0);
              },
              itemCount: _selectedUsers.length + _selectableUsers.length,
              itemBuilder: (BuildContext context, int index) {
                if (index < _selectedUsers.length) {
                  User selectedUser = _selectedUsers[index];
                  return ListTile(
                    leading: CircleAvatar(
                      radius: 28,
                      child: CachedNetworkImage(
                        imageUrl: selectedUser.profileImageUrl,
                        imageBuilder: (context, imageProvider) => Container(
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(30)),
                            image: DecorationImage(
                                image: imageProvider, fit: BoxFit.cover),
                          ),
                        ),
                      ),
                    ),
                    title: Text(
                      selectedUser.fullname,
                      style: TextStyle(fontSize: 14),
                    ),
                    
                    trailing: Icon(Icons.check_circle, color: blueColor),
                    onTap: () {
                      _selectedUsers.remove(selectedUser);
                      _selectableUsers.insert(0, selectedUser);
                      setState(() {});
                    },
                  );
                } else {
                  int userIndex = index - _selectedUsers.length;
                  User user = _selectableUsers[userIndex];

                  return ListTile(
                    leading: CircleAvatar(
                      radius: 28,
                      child: CachedNetworkImage(
                        imageUrl: user.profileImageUrl,
                        imageBuilder: (context, imageProvider) => Container(
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(50)),
                            image: DecorationImage(
                                image: imageProvider, fit: BoxFit.cover),
                          ),
                        ),
                      ),
                    ),
                    title: Text(
                      user.fullname,
                      style: TextStyle(fontSize: 14),
                    ),
                    
                    trailing: Icon(
                      CupertinoIcons.circle,
                      color: Colors.grey,
                    ),
                    onTap: () {
                      _selectedUsers.add(user);
                      _selectableUsers.remove(user);
                      setState(() {});
                    },
                  );
                }
              },
            ),
          ),
        ],
      ),
    );
  }
}

2 Answers 2

1

Try this:

onSubmitted: (input) async {
    if (input.trim().isNotEmpty) {
        List<User> users = await Provider.of<DatabaseService>(context, listen: false).searchUsers(currentUserUid, input);
        
        var setAllUsers = Set.from(users);
        var setSelectedUsers = Set.from(selectedUsers);
        
        setState(() {
            selectableUsers.addAll(List.from(setAllUsers.difference(setSelectedUsers)));
        });
    }
}),

You also need add Equatable package to your user model class, lets assume this is your model class:

class User extends Equatable {// <-- add this
  final String fullName;
  final String avatar;
  final int phone;
  const User({
    required this.fullName,
    required this.avatar,
    required this.phone,
  });

  @override
  List<Object?> get props => [fullName, avatar, phone];// <-- add this
}
Sign up to request clarification or add additional context in comments.

14 Comments

Thank you! I am getting this error. The instance member 'allUsers' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression.
List<User> _users = []; List<User> _selectedUsers = []; List _selectableUsers = []; var setAllUsers = Set.from(_users); var setSelectedUsers = Set.from(_selectedUsers); List selectableUsers = List.from(_users.difference(_selectedUsers));
I updated my answer again, check it out, @Eren
awesome! So final piece is that I have a search function but it doesn't pick the users when I use your suggestion. It does pick all users if use "all users" onSubmitted: (input) async { if (input.trim().isNotEmpty) { List<User> users = await Provider.of<DatabaseService>(context, listen: false) .searchUsers(currentUserUid, input); setState(() { _selectableUsers = users; }); } }
super! Thanks again @eamirho3ein. I really appreciate it...
|
0

A basic way of doing will be checking each item like

  List<User> allusers = [];
  List<User> selectedUsers = [];
  List<User> selectableUsers = [];
  for (final user in allusers) {
    if (!selectableUsers.contains(user)) selectableUsers.add(user);
  }

1 Comment

Thank you! I tried this approach but it didn't work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.