DM List
Loading preview
Starting the Flutter app
Conversations with avatar, last message, unread badge
import 'package:flutter/material.dart';
const _conversations = [
{'user': 'Alice', 'last': 'Hey, how are you?', 'unread': true},
{'user': 'Bob', 'last': 'See you tomorrow', 'unread': false},
];
class DmList extends StatelessWidget {
const DmList({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Messages')),
body: ListView.builder(
itemCount: _conversations.length,
itemBuilder: (context, i) {
final c = _conversations[i];
return ListTile(
leading: Stack(
children: [
CircleAvatar(child: Text((c['user'] as String)[0])),
if (c['unread'] == true)
Positioned(
right: 0,
bottom: 0,
child: Container(
width: 12,
height: 12,
decoration: const BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: const Center(
child: Text('1', style: TextStyle(fontSize: 8, color: Colors.white)),
),
),
),
],
),
title: Text(
c['user'] as String,
style: TextStyle(
fontWeight: c['unread'] == true
? FontWeight.bold
: FontWeight.normal,
),
),
subtitle: Text(c['last'] as String),
trailing: const Text('2m', style: TextStyle(fontSize: 12)),
);
},
),
);
}
}
Add it to your project
Copies the Dart source into your app, so you own it. Flutter SDK only, no extra packages.
First time? Run dart pub global activate fluttertemplates_dev, or read the CLI guide.
How it works
Two entries from _conversations go through ListView.builder. A Stack in leading overlays a 12px blue badge when unread is true, and the name turns bold. The badge digit '1' and timestamp '2m' are hardcoded, so neither comes from the data. ListTile has no onTap, so rows can’t open a chat.
Adapting it
- Use a conversation model with
unreadCountand aDateTime, replacing the'1'and'2m'literals. - Add
onTapto theListTileto push your chat screen. - Feed
_conversationsfrom a stream so new messages reorder the list.