This is documentation for Stream Chat Flutter SDK v7, which is nolonger actively maintained. For up-to-date documentation, see the latest version (v8).

Users State & Filtering

A Widget For Controlling A List Of Users

Find the pub.dev documentation here

Background

The StreamUserListController is a controller class that allows you to control a list of users. StreamUserListController is a required parameter of the StreamUserListView widget. Check the StreamUserListView documentation to read more about that.

Basic Example

Building a custom user list is a very common task. Here is an example of how to use the StreamUserListController to build a simple list with pagination.

First of all we should create an instance of the StreamUserListController and provide it with the StreamChatClient instance. You can also add a Filter, a list of SortOptions and other pagination-related parameters.

class UserListPageState extends State<UserListPage> {
  /// Controller used for loading more data and controlling pagination in
  /// [StreamUserListController].
  late final userListController = StreamUserListController(
    client: StreamChatCore.of(context).client,
  );

Make sure you call userListController.doInitialLoad() to load the initial data and userListController.dispose() when the controller is no longer required.

@override
void initState() {
  userListController.doInitialLoad();
  super.initState();
}

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

The StreamUserListController is basically a PagedValueNotifier that notifies you when the list of users has changed. You can use a PagedValueListenableBuilder to build your UI depending on the latest users.

@override
Widget build(BuildContext context) => Scaffold(
      body: PagedValueListenableBuilder<int, User>(
        valueListenable: userListController,
        builder: (context, value, child) {
          return value.when(
            (users, nextPageKey, error) => LazyLoadScrollView(
              onEndOfPage: () async {
                if (nextPageKey != null) {
                  userListController.loadMore(nextPageKey);
                }
              },
              child: ListView.builder(
                /// We're using the users length when there are no more
                /// pages to load and there are no errors with pagination.
                /// In case we need to show a loading indicator or and error
                /// tile we're increasing the count by 1.
                itemCount: (nextPageKey != null || error != null)
                    ? users.length + 1
                    : users.length,
                itemBuilder: (BuildContext context, int index) {
                  if (index == users.length) {
                    if (error != null) {
                      return TextButton(
                          onPressed: () {
                            userListController.retry();
                          },
                          child: Text(error.message),
                        );
                    }
                    return const CircularProgressIndicator();
                  }

                  final _item = users[index];
                  return ListTile(
                    title: Text(_item.name),
                  );
                },
              ),
            ),
            loading: () => const Center(
              child: SizedBox(
                height: 100,
                width: 100,
                child: CircularProgressIndicator(),
              ),
            ),
            error: (e) => Center(
              child: Text(
                'Oh no, something went wrong. '
                'Please check your config. $e',
              ),
            ),
          );
        },
      ),
    );

In this case we’re using the LazyLoadScrollView widget to load more data when the user scrolls to the bottom of the list.

© Getstream.io, Inc. All Rights Reserved.