Skip to main content

Chat Page Builders

ChatPage exposes builders for the page app bar, message rows, list header/footer, empty state, and custom message content. The default input area does not expose a full replacement builder; configure it with MessageInputConfig.

Page-Level Builders

ChatPage constructor fields:

  • appBarBuilder
  • messageBuilder
  • headerBuilder
  • footerBuilder
  • emptyBuilder
  • customMessageBubbleBuilders

Interaction callbacks:

  • onMessageTap
  • onMessageDoubleTap
  • onMessageLongPress
  • onMessageAvatarTap
  • onMessageAvatarLongPress
  • onMessageSwipe

Builder Signatures

Dart
typedef ChatAppBarBuilder = PreferredSizeWidget Function(
BuildContext context,
ChatAppBarConfig config,
);

typedef MessageWidgetBuilder = Widget Function(
BuildContext context,
Message message,
ChatPageConfig config,
);

typedef ChatMessageBubbleBuilder = Widget Function(
BuildContext context,
Message message,
ChatPageConfig config,
);

messageBuilder replaces the whole message row. customMessageBubbleBuilders replaces the content widget for a specific MessageType while the built-in message row keeps handling avatar, alignment, status, read-receipt display, and the long-press menu.

Custom App Bar

Dart
ChatPage(
channel: channel,
appBarBuilder: (context, config) {
return AppBar(
toolbarHeight: config.height,
title: Text(config.title ?? 'Chat'),
centerTitle: config.centerTitle,
actions: config.actions,
);
},
)
Dart
ChatPage(
channel: channel,
headerBuilder: (context) {
return const Padding(
padding: EdgeInsets.all(12),
child: Text('This channel is monitored for quality.'),
);
},
footerBuilder: (context) {
return const SizedBox(height: 12);
},
emptyBuilder: (context) {
return const Center(child: Text('No messages yet'));
},
)

Replace a Whole Message Row

Dart
ChatPage(
channel: channel,
messageBuilder: (context, message, config) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text('Message id: ${message.messageId ?? '-'}'),
),
),
);
},
)

Use messageBuilder only when you want to own the full row. For a single custom message type, prefer customMessageBubbleBuilders; see Custom message bubble builders.