Channel List View Confused about "Channel List View"?
Let us know how we can improve our documentation:
Confused about "Channel List View"?
Let us know how we can improve our documentation:
ChannelListView
is responsible for displaying list of channels. It also supports loading and empty states. By default, a single list item shows the channel name, user's read state, last message, and the time of the last message. It also implements swiping behaviour which allows handling different actions on the channel:

You can use the view in your layout as shown below:
1
2
3
4
<io.getstream.chat.android.ui.channel.list.ChannelListView
android:id="@+id/channelsView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Binding with a ViewModelCopied!Confused about "
,[object Object]"?
Let us know how we can improve our documentation:
Confused about " ,[object Object]"?
Let us know how we can improve our documentation:
ChannelListView
allows you to display different channels list states and handle common user's interactions, but it doesn't contain logic for getting channels from the Stream API. The Android SDK comes with ChannelListViewModel
which contains default logic for this view, which can be easily bound to it using bindView
:
1
2
3
4
5
6
7
8
9
10
11
12
val viewModel: ChannelListViewModel by viewModels {
ChannelListViewModelFactory(
filter = Filters.and(
Filters.eq("type", "messaging"),
Filters.`in`("members", listOf(ChatDomain.instance().currentUser.id)),
),
sort = ChannelsViewModel.DEFAULT_SORT,
limit = 30,
)
}
// Bind it with ChannelListView
viewModel.bindView(channelListView, viewLifecycleOwner)
1
2
3
4
5
6
7
8
9
10
11
12
13
// Get ViewModel
FilterObject filter = Filters.and(
Filters.eq("type", "messaging"),
Filters.in("members", singletonList(ChatDomain.instance().getCurrentUser().getId()))
);
int limit = 30;
ChannelListViewModelFactory factory = new ChannelListViewModelFactory(filter, ChannelListViewModel.DEFAULT_SORT, limit);
ChannelListViewModel viewModel = new ViewModelProvider(this, factory)
.get(ChannelListViewModel.class);
// Bind it with ChannelListView
ChannelListViewModelBinding.bind(viewModel, channelListView, getViewLifecycleOwner());
This call connects the ViewModel with the view and from that point, different channels view states, as well as channel's pagination, will be handled automatically.
It's worth mentioning that you don't need to query channels by yourself. The first call will be done during the creation of ChannelListViewModel
and the list will be kept updated automatically based on received events.
Handling Channel ActionsCopied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
Confused about "[object Object]"?
Let us know how we can improve our documentation:
ChannelListView
comes with a set of channel actions out of the box. You can:
See channel members
Delete the channel if you have sufficient permissions
Leave the channel if it's a group channel

There are some actions (e.g. clicking on member or Viewing Info) that require additional handling:
1
2
3
4
5
6
7
channelListView.setChannelInfoClickListener { channel ->
// Handle Channel Info Click
}
channelListView.setUserClickListener { user ->
// Handle Member Click
}
1
2
3
4
5
6
7
channelListView.setChannelInfoClickListener((channel) -> {
// Handle Channel Info Click
});
channelListView.setUserClickListener((user) -> {
// Handle Member Click
});
Handling User InteractionsCopied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
Confused about "[object Object]"?
Let us know how we can improve our documentation:
ChannelListView
exposes multiple methods for setting listeners for user interactions handling, that includes different user clicks handling:
1
2
3
4
5
6
7
8
channelListView.setChannelItemClickListener { channel ->
// Handle Channel Click
}
channelListView.setChannelLongClickListener { channel ->
// Handle Channel Click
true
}
1
2
3
4
5
6
7
8
channelListView.setChannelItemClickListener((channel) -> {
// Handle Channel Click
});
channelListView.setChannelLongClickListener((channel) -> {
// Handle Channel Long Click
return true;
});
A full list of available listeners to set can be found here.
Customizing Default ViewsCopied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
Confused about "[object Object]"?
Let us know how we can improve our documentation:
The view allows setting custom loading and empty views, as well as and separators via code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Create loading view and layout params
val loadingView = ProgressBar(context)
val layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER
)
channelListView.setEmptyStateView(loadingView, layoutParams)
// Create empty state view and use default layout params
val emptyStateView = TextView(context).apply {
text = "No channels available"
}
channelListView.setEmptyStateView(emptyStateView)
// Set custom item separator drawable
channelListView.setItemSeparator(R.drawable.stream_ui_divider)
// Add separator to the last item
channelListView.setShouldDrawItemSeparatorOnLastItem(true)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Create loading view and layout params
ProgressBar loadingView = new ProgressBar(getContext());
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER
);
channelListView.setEmptyStateView(loadingView, layoutParams);
// Create empty state view and use default layout params
TextView emptyStateView = new TextView(getContext());
emptyStateView.setText("No channels available");
channelsView.setEmptyStateView(emptyStateView);
// Set custom item separator drawable
channelListView.setItemSeparator(R.drawable.stream_ui_divider);
// Add separator to the last item
channelListView.setShouldDrawItemSeparatorOnLastItem(true);
Custom ViewHolder FactoryCopied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
Confused about "[object Object]"?
Let us know how we can improve our documentation:
ChannelListView
provides a mechanism for completely changing the default view holders, as well as introducing different types of views. All you need to do is to provide your own ChannelListItemViewHolderFactory
implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class CustomChannelListItemViewHolderFactory : ChannelListItemViewHolderFactory() {
override fun getItemViewType(item: ChannelListItem): Int {
// Override together with createViewHolder() to introduce different view holder types
return super.getItemViewType(item)
}
override fun createViewHolder(parentView: ViewGroup, viewType: Int): BaseChannelListItemViewHolder {
// Override to create custom create view holder logic
return super.createViewHolder(parentView, viewType)
}
override fun createChannelViewHolder(parentView: ViewGroup): BaseChannelListItemViewHolder {
// Create custom channel view holder
return super.createChannelViewHolder(parentView)
}
override fun createLoadingMoreViewHolder(parentView: ViewGroup): BaseChannelListItemViewHolder {
// Create custom loading more view holder
return super.createLoadingMoreViewHolder(parentView)
}
}
// Create custom view holder factory
val customFactory = CustomChannelListItemViewHolderFactory()
// Set custom view holder factory
channelListView.setViewHolderFactory(customFactory)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class CustomChannelListItemViewHolderFactory extends ChannelListItemViewHolderFactory {
@Override
public int getItemViewType(@NotNull ChannelListItem item) {
// Override together with createViewHolder() to introduce different view holder types
return super.getItemViewType(item);
}
@NotNull
@Override
public BaseChannelListItemViewHolder createViewHolder(@NotNull ViewGroup parentView, int viewType) {
// Override to create custom create view holder logic
return super.createViewHolder(parentView, viewType);
}
@NotNull
@Override
protected BaseChannelListItemViewHolder createChannelViewHolder(@NotNull ViewGroup parentView) {
// Create custom channel view holder
return super.createChannelViewHolder(parentView);
}
@NotNull
@Override
protected BaseChannelListItemViewHolder createLoadingMoreViewHolder(@NotNull ViewGroup parentView) {
// Create custom loading more view holder
return super.createLoadingMoreViewHolder(parentView);
}
}
// Create custom view holder factory
CustomChannelListItemViewHolderFactory customFactory = new CustomChannelListItemViewHolderFactory();
// Set custom view holder factory
channelListView.setViewHolderFactory(customFactory);
NOTE: The View Holder Factory needs to be set before ChannelListView
initializes its adapter.
Other CustomizationsCopied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
Confused about "[object Object]"?
Let us know how we can improve our documentation:
The view is also configurable using attributes. A list of available attributes can be found here.