StreamMessageListView(
...
)
Message List View
Customizing Text Messages
Introduction
Every application provides a unique look and feel to their own messaging interface including and not limited to fonts, colors, and shapes.
This guide details how to customize message text in the StreamMessageListView
/ StreamMessageWidget
in the
Stream Chat Flutter UI SDK.
This guide is specifically for the StreamMessageListView
but if you intend to display a StreamMessageWidget
separately, follow the same process without the .copyWith
and use the default constructor instead.
Basics of customizing a StreamMessageWidget
First, add a StreamMessageListView
in the appropriate place where you intend to display messages from a
channel.
Now, we use the messageBuilder
parameter to build a custom message. The builder function also provides
the default implementation of the StreamMessageWidget
so that we can change certain aspects of the widget
without redoing all of the default parameters.
In earlier versions of the SDK, some StreamMessageWidget
parameters were exposed directly through the StreamMessageListView
,
however, this quickly becomes hard to maintain as more parameters and customizations are added to the
StreamMessageWidget
. Newer version utilise a cleaner interface to change the parameters by supplying a
default message implementation as aforementioned.
StreamMessageListView(
...
messageBuilder: (context, messageDetails, messageList, defaultWidget) {
return defaultWidget;
},
)
We use .copyWith()
to customize the widget:
StreamMessageListView(
...
messageBuilder: (context, messageDetails, messageList, defaultWidget) {
return defaultWidget.copyWith(
...
);
},
)
Customizing text
If you intend to simply change the theme for the text, you need not recreate the whole widget. The
StreamMessageWidget
has a messageTheme
parameter that allows you to pass the theme for most aspects
of the message.
StreamMessageListView(
...
messageBuilder: (context, messageDetails, messageList, defaultWidget) {
return defaultWidget.copyWith(
messageTheme: StreamMessageThemeData(
...
messageTextStyle: TextStyle(),
),
);
},
)
If you want to replace the entire text widget in the StreamMessageWidget
, you can use the textBuilder
parameter which provides a builder for creating a widget to substitute the default text.parameter
StreamMessageListView(
...
messageBuilder: (context, messageDetails, messageList, defaultWidget) {
return defaultWidget.copyWith(
textBuilder: (context, message) {
return Text(message.text ?? '');
},
);
},
)
Adding Hashtags
To add elements like hashtags, we can override the textBuilder
in the StreamMessageWidget:
StreamMessageListView(
...
messageBuilder: (context, messageDetails, messageList, defaultWidget) {
return defaultWidget.copyWith(
textBuilder: (context, message) {
final text = _replaceHashtags(message.text)?.replaceAll('\n', '\\\n');
final messageTheme = StreamChatTheme.of(context).ownMessageTheme;
if (text == null) return const SizedBox();
return MarkdownBody(
data: text,
onTapLink: (
String link,
String? href,
String title,
) {
// Do something with tapped hashtag
},
styleSheet: MarkdownStyleSheet.fromTheme(
Theme.of(context).copyWith(
textTheme: Theme.of(context).textTheme.apply(
bodyColor: messageTheme.messageTextStyle?.color,
decoration: messageTheme.messageTextStyle?.decoration,
decorationColor: messageTheme.messageTextStyle?.decorationColor,
decorationStyle: messageTheme.messageTextStyle?.decorationStyle,
fontFamily: messageTheme.messageTextStyle?.fontFamily,
),
),
).copyWith(
a: messageTheme.messageLinksStyle,
p: messageTheme.messageTextStyle,
),
);
},
);
},
)
String? _replaceHashtags(String? text) {
if (text == null) return null;
final exp = RegExp(r"\B#\w\w+");
String result = text;
exp.allMatches(text).forEach((match){
text = text!.replaceAll(
'${match.group(0)}', '[${match.group(0)}](/chat/docs/sdk/flutter/v5/customization/custom-widgets/customize_text_messages/${match.group(0/)?.replaceAll(' ', '')})');
});
return result;
}
We can replace the hashtags using RegEx and add links for the MarkdownBody which is done here in the
_replaceHashtags()
function.
Inside the textBuilder, we use the flutter_markdown
package to build our hashtags as links.