Home > OS >  Flutter User Filter
Flutter User Filter

Time:10-30

  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(() {});
                    },
                  );
                }
              },
            ),
          ),
        ],
      ),
    );
  }
}

CodePudding user response:

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
}

CodePudding user response:

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);
  }
  • Related