Message List View
Confused about "Message List View"?
Let us know how we can improve our documentation:
stream-chat-android
UI implementation. Check out MessageListView in our new UI components for an updated version.The message list renders a list of messages. It implements all the features you expect from a chat/message list view:
Reactions
Editing
Typing indicators
Read state
Rich URL previews
Threads

The example below shows how to use the MessageListView in your layout:
1
2
3
4
<com.getstream.sdk.chat.view.MessageListView
android:id="@+id/messageList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
To render the list of messages you need to connect the view to the MessageListViewModel using MessageListViewModelBinding:
1
2
3
4
5
// Get a ViewModel instance
val messageListViewModel: MessageListViewModel by viewModels { ChannelViewModelFactory(channel.cid) }
// Bind ViewModel and View together
messagesViewModel.bindView(messageListView, lifecycleOwner)
1
2
3
4
5
6
7
// Get a ViewModel instance
ChannelViewModelFactory factory = new ChannelViewModelFactory(channel.getCid());
MessageListViewModel viewModel = new ViewModelProvider(this, factory)
.get(MessageListViewModel.class);
// Bind ViewModel and View together
MessageListViewModelBinding.bind(viewModel, messageListView, lifecycle);
The view model provides the view with:
The list of messages
The ability to mark messages as read
Pagination/ loading more content
Keeping track if there are new messages (that are not shown since you're scrolled up)
The current channel
Edit message state
Start thread state
Button to scroll to the bottom.
Count of new messages.
Listeners
Copied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
The following listeners can be set:
setMessageClickListener
setMessageLongClickListener
setMessageRetryListener
setAttachmentClickListener
setReactionViewClickListener
setUserClickListener
setReadStateClickListener
setOnStartThreadListener
Handlers
Copied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
The following handlers can be set:
setEndRegionReachedHandler
setLastMessageReadHandler
setOnMessageEditHandler
setOnMessageDeleteHandler
setOnStartThreadHandler
setOnMessageFlagHandler
setOnSendGiphyHandler
setOnMessageRetryHandler
Customizations
Copied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
The message list view exposes multiple methods which might be helpful if you decide not to use default view model but create your own controller instead:
init()
setScrollButtonBehaviour()
setNewMessagesBehaviour()
setScrollButtonBackgroundResource()
setScrollButtonBackground()
setScrollButtonIconResource()
setScrollButtonIcon()
setAttachmentViewHolderFactory()
setMessageViewHolderFactory()
setBubbleHelper()
displayNewMessage()
scrollToBottom()
setLoadingView()
setEmptyStateView()
Customizing the message list using attributes
Copied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
You can use the following properties in your XML to change your MessageListView:
Behaviour
Copied!Confused about "Behaviour"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamNewMessagesBehaviour | enum. Options: 1- scroll_to_bottom, 2 - count_new_messages | Behaviour for new messages when user is scrolling in the chat. | count_new_messages | ✓ |
Scroll to bottom button
Copied!Confused about "Scroll to bottom button"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamNewMessagesTextSingle | string | Text for one new message. Example: "1 New message" | - | ✓ |
app:streamNewMessagesTextPlural | string | Text for many new messages. Example: "5 New messages" | - | ✓ |
app:streamScrollButtonBackground | reference | Background of the scroll to bottom button - This can be useful to change the color and shape of the button. | round shape with accent color | ✓ |
app:streamButtonIcon | reference | Icon in the button | Bottom arrow | ✓ |
app:streamDefaultScrollButtonEnabled | boolean | Enable or disable the Scroll Button | True | ✓ |
Avatar
Copied!Confused about "Avatar"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamAvatarWidth | dimension | 32dp | ✓ | |
app:streamAvatarHeight | dimension | 32dp | ✓ | |
app:streamAvatarBorderWidth | dimension | 3dp | ✓ | |
app:streamAvatarBorderColor | color | WHITE | ✓ | |
app:streamAvatarBackGroundColor | color | stream_gray_dark | ✓ | |
app:streamAvatarTextSize | dimension | 14sp | ✓ | |
app:streamAvatarTextColor | color | WHITE | ✓ | |
app:streamAvatarTextStyle | normal, bold, italic | bold | ✓ | |
app:streamAvatarTextFont | reference | - | ✓ | |
app:streamAvatarTextFontAssets | string | - | ✓ |
Read State
Copied!Confused about "Read State"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamShowReadState | boolean | true | ✓ | |
app:streamReadStateAvatarWidth | dimension | 14dp | ✓ | |
app:streamReadStateAvatarHeight | dimension | 14dp | ✓ | |
app:streamReadStateTextSize | dimension | 8sp | ✓ | |
app:streamReadStateTextColor | color | BLACK | ✓ | |
app:streamReadStateTextStyle | normal, bold, italic | bold | ✓ | |
app:streamReadStateTextFont | reference | - | ✓ | |
app:streamReadStateTextFontAssets | string | - | ✓ | |
app:streamShowDeliveredState | boolean | true | ✓ | |
app:streamShowReadState | boolean | true | ✓ |
Reactions
Copied!Confused about "Reactions"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamReactionEnabled | boolean | true | ✓ | |
app:streamrReactionViewBgDrawable | reference | - | ✓ | |
app:streamReactionViewBgColor | color | #292929 | ✓ | |
app:streamReactionViewEmojiSize | dimension | 12sp | ✓ | |
app:streamReactionViewEmojiMargin | dimension | 1dp | ✓ | |
app:streamReactionInputbgColor | color | #292929 | ✓ | |
app:streamReactionInputEmojiSize | dimension | 27sp | ✓ | |
app:streamReactionInputEmojiMargin | dimension | 5dp | ✓ |
Message
Copied!Confused about "Message"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamMessageTextSizeMine | dimension | 15sp | ✓ | |
app:streamMessageTextSizeTheirs | dimension | 15sp | ✓ | |
app:streamMessageTextColorMine | color | BLACK | ✓ | |
app:streamMessageTextColorTheirs | color | BLACK | ✓ | |
app:streamMessageTextStyleMine | normal, bold, italic | normal | ✓ | |
app:streamMessageTextStyleTheirs | normal, bold, italic | normal | ✓ | |
app:streamMessageTextFontMine | reference | - | ✓ | |
app:streamMessageTextFontTheirs | reference | - | ✓ | |
app:streamMessageTextFontMineAssets | string | - | ✓ | |
app:streamMessageTextFontTheirsAssets | string | - | ✓ | |
app:streamMessageBubbleDrawableMine | reference | - | ✓ | |
app:streamMessageBubbleDrawableTheirs | reference | - | ✓ | |
app:streamMessageTopLeftCornerRadiusMine | dimension | 16dp | ✓ | |
app:streamMessageTopRightCornerRadiusMine | dimension | 16dp | ✓ | |
app:streamMessageBottomRightCornerRadiusMine | dimension | 2dp | ✓ | |
app:streamMessageBottomLeftCornerRadiusMine | dimension | 16dp | ✓ | |
app:streamMessageTopLeftCornerRadiusTheirs | dimension | 16dp | ✓ | |
app:streamMessageTopRightCornerRadiusTheirs | dimension | 16dp | ✓ | |
app:streamMessageBottomRightCornerRadiusTheirs | dimension | 16dp | ✓ | |
app:streamMessageBottomLeftCornerRadiusTheirs | dimension | 2dp | ✓ | |
app:streamMessageBackgroundColorMine | color | #0D000000 | ✓ | |
app:streamMessageBackgroundColorTheirs | color | WHITE | ✓ | |
app:streamMessageBorderColorMine | color | #14000000 | ✓ | |
app:streamMessageBorderColorTheirs | color | #14000000 | ✓ | |
app:streamMessageBorderWidthMine | dimension | 1dp | ✓ | |
app:streamMessageBorderWidthTheirs | dimension | 1dp | ✓ | |
app:streamMessageLinkTextColorMine | color | - | ✓ | |
app:streamMessageLinkTextColorTheirs | color | - | ✓ |
Attachment
Copied!Confused about "Attachment"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamAttachmentBackgroundColorMine | color | streamMessageBackgroundColorMine | ✓ | |
app:streamAttachmentBackgroundColorTheirs | color | streamMessageBackgroundColorTheirs | ✓ | |
app:streamAttachmentBorderColorMine | color | streamMessageBorderColorMine | ✓ | |
app:streamAttachmentBorderColorTheirs | color | streamMessageBorderColorTheirs | ✓ | |
app:streamAttachmentTitleTextSizeMine | dimension | 13sp | ✓ | |
app:streamAttachmentTitleTextSizeTheirs | dimension | 13sp | ✓ | |
app:streamAttachmentTitleTextColorMine | color | #026DFE | ✓ | |
app:streamAttachmentTitleTextColorTheirs | color | #026DFE | ✓ | |
app:streamAttachmentTitleTextStyleMine | normal, bold, italic | bold | ✓ | |
app:streamAttachmentTitleTextStyleTheirs | normal, bold, italic | bold | ✓ | |
app:streamAttachmentTitleTextFontMine | reference | - | ✓ | |
app:streamAttachmentTitleTextFontTheirs | reference | - | ✓ | |
app:streamAttachmentTitleTextFontAssetsMine | string | - | ✓ | |
app:streamAttachmentTitleTextFontAssetsTheirs | string | - | ✓ | |
app:streamAttachmentDescriptionTextSizeMine | dimension | 11sp | ✓ | |
app:streamAttachmentDescriptionTextSizeTheirs | dimension | 11sp | ✓ | |
app:streamAttachmentDescriptionTextColorMine | color | stream_gray_dark | ✓ | |
app:streamAttachmentDescriptionTextColorTheirs | color | stream_gray_dark | ✓ | |
app:streamAttachmentDescriptionTextStyleMine | normal, bold, italic | normal | ✓ | |
app:streamAttachmentDescriptionTextStyleTheirs | normal, bold, italic | normal | ✓ | |
app:streamAttachmentDescriptionTextFontMine | reference | - | ✓ | |
app:streamAttachmentDescriptionTextFontTheirs | reference | - | ✓ | |
app:streamAttachmentDescriptionTextFontAssetsMine | string | - | ✓ | |
app:streamAttachmentDescriptionTextFontAssetsTheirs | string | - | ✓ | |
app:streamAttachmentFileSizeTextSizeMine | dimension | 12sp | ✓ | |
app:streamAttachmentFileSizeTextSizeTheirs | dimension | 12sp | ✓ | |
app:streamAttachmentFileSizeTextColorMine | color | stream_gray_dark | ✓ | |
app:streamAttachmentFileSizeTextColorTheirs | color | stream_gray_dark | ✓ | |
app:streamAttachmentFileSizeTextStyleMine | normal, bold, italic | bold | ✓ | |
app:streamAttachmentFileSizeTextStyleTheirs | normal, bold, italic | bold | ✓ | |
app:streamAttachmentFileSizeTextFontMine | reference | - | ✓ | |
app:streamAttachmentFileSizeTextFontTheirs | reference | - | ✓ | |
app:streamAttachmentFileSizeTextFontAssetsMine | string | - | ✓ | |
app:streamAttachmentFileSizeTextFontAssetsTheirs | string | - | ✓ |
Date Separator
Copied!Confused about "Date Separator"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamDateSeparatorDateTextSize | dimension | 12sp | ✓ | |
app:streamDateSeparatorDateTextColor | color | stream_gray_dark | ✓ | |
app:streamDateSeparatorDateTextStyle | normal, bold, italic | bold | ✓ | |
app:streamDateSeparatorDateTextFont | reference | - | ✓ | |
app:streamDateSeparatorDateTextFontAssets | string | - | ✓ | |
app:streamDateSeparatorLineWidth | dimension | 1dp | ✓ | |
app:streamDateSeparatorLineColor | color | stream_gray_dark | ✓ | |
app:streamDateSeparatorLineDrawable | reference | - | ✓ |
Message details
Copied!Confused about "Message details"?
Let us know how we can improve our documentation:
name | type | description | default | optional |
---|---|---|---|---|
app:streamMessageUserNameTextSize | dimension | 11sp | ✓ | |
app:streamMessageUserNameTextColor | color | stream_gray_dark | ✓ | |
app:streamMessageUserNameTextStyle | normal, bold, italic | normal | ✓ | |
app:streamMessageUserNameTextFont | reference | - | ✓ | |
app:streamMessageUserNameTextFontAssets | string | - | ✓ | |
app:streamMessageDateTextSizeMine | dimension | 11sp | ✓ | |
app:streamMessageDateTextSizeTheirs | dimension | 11sp | ✓ | |
app:streamMessageDateTextColorMine | color | stream_gray_dark | ✓ | |
app:streamMessageDateTextColorTheirs | color | stream_gray_dark | ✓ | |
app:streamMessageDateTextStyleMine | normal, bold, italic | normal | ✓ | |
app:streamMessageDateTextStyleTheirs | normal, bold, italic | normal | ✓ | |
app:streamMessageDateTextFontMine | reference | - | ✓ | |
app:streamMessageDateTextFontAssetsMine | string | - | ✓ | |
app:streamUserNameShow | boolean | true | ✓ | |
app:streamMessageDateShow | boolean | true | ✓ |
Copied!
Confused about " "?
Let us know how we can improve our documentation:
Customizing the message list - BubbleHelper
Copied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
Message Bubbles can be quite complex in messaging apps. Many messaging apps will change the bubble layout based on:
The message position in a group of messages (top, middle, bottom)
The overall position of the message on the screen
If the message is yours or written by someone else
If the message has attachments
To allow you to customize the message bubble rendering we allow you to set your own message Bubble Helper. Here's an example of how to set a custom bubble helper.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
MessageListView messageList = findViewById(R.id.messageList);
messageList.setBubbleHelper(new MessageListView.BubbleHelper() {
@Override
public Drawable getDrawableForMessage(Message message, Boolean mine, List<MessageListItem.Position> positions) {
return null;
}
@Override
public Drawable getDrawableForAttachment(Message message, Boolean mine, List<MessageListItem.Position> positions, Attachment attachment) {
return null;
}
@Override
public Drawable getDrawableForAttachmentDescription(Message message, Boolean mine, List<MessageListItem.Position> positions) {
return null;
}
});
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
val messageList = findViewById(R.id.messageList)
messageList.setBubbleHelper(object: MessageListView.BubbleHelper {
override fun getDrawableForAttachment(
message: Message,
mine: Boolean,
positions: List<MessageListItem.Position>,
attachment: Attachment
): Drawable {
TODO("not implemented")
}
override fun getDrawableForAttachmentDescription(
message: Message,
mine: Boolean,
positions: List<MessageListItem.Position>
): Drawable {
TODO("not implemented")
}
override fun getDrawableForMessage(
message: Message,
mine: Boolean,
positions: List<MessageListItem.Position>
): Drawable {
TODO("not implemented")
}
})
For some messaging use cases, you'll run into the issue that you need to create many different drawables. One library that can help with that is DrawableToolbox which simplifies the programmatic creation of drawables.
Custom Attachment Type
Copied!Confused about "[object Object]"?
Let us know how we can improve our documentation:
You can customize the layout for a specific type of message or attachment. Example use cases include adding a form, a live location, a checkout flow, etc.
These are the steps for creating your own attachment type:
Implement an Attachment ViewHolder, with your custom layout
Create an AttachmentViewHolderFactory that creates instances of your ViewHolder
Tell the MessageListView to use your custom AttachmentViewHolderFactory
The Kotlin Chat Tutorial explains this in more detail.
Creating custom scroll-to-bottom button
Copied!Confused about "Creating custom scroll-to-bottom button"?
Let us know how we can improve our documentation:
Although it is possible to customize the default button, sometimes a user may want a completely different view.
As MessageListView extends from ConstraintLayout, any view can be inserted inside of it and used as the button to scroll to button and show the count of new messages.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<com.getstream.sdk.chat.view.MessageListView
android:id="@+id/messageListView"
android:layout_width="match_parent"
app:streamMessageDateShow="true"
android:clipToPadding="false"
android:paddingBottom="@dimen/padding_medium"
app:streamNewMessagesBehaviour="count_new_messages"
app:streamDefaultButtonEnabled="false"
>
<Button
android:id="@+id/scrollBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:animateLayoutChanges="true"
android:text="Scroll - 1 New message"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
</com.getstream.sdk.chat.view.MessageListView>
Then the behaviour of the button can be set with the method setScrollButtonBehaviour
implementing the interface MessageListView.ScrollButtonBehaviour
, as an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
messageListView.setScrollButtonBehaviour(new MessageListView.ScrollButtonBehaviour() {
@Override
public void userScrolledUp() {
scrollBtn.setVisibility(View.VISIBLE);
}
@Override
public void userScrolledToTheBottom() {
scrollBtn.setVisibility(View.GONE);
}
@Override
public void onUnreadMessageCountChanged(int count) {
if (count == 0) {
scrollBtn.setText("Scroll");
} else if (count == 1) {
scrollBtn.setText("Scroll - 1 New Message");
} else {
scrollBtn.setText("Scroll - " + count + " New Messages");
}
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
messageListView.setScrollButtonBehaviour(object : MessageListView.ScrollButtonBehaviour {
override fun userScrolledUp() {
scrollBtn.visibility = View.VISIBLE
}
override fun userScrolledToTheBottom() {
scrollBtn.visibility = View.GONE
}
override fun onUnreadMessageCountChanged(count: Int) {
when (count) {
0 -> scrollBtn.text = "Scroll"
1 -> scrollBtn.text = "Scroll - 1 New Message"
else -> scrollBtn.text = "Scroll - $count New Messages"
}
}
})