I am working on a Flutter chat implementation, where for each chat left-aligned message I would like the ListTile to start with a Column that will contain 2 widgets:
- the user avatar image
- their name below
The issue I am running into is that the Column will not expand, and image gets cropped. Here is an example. I have tried 2 variations, where I try to set height/width at 70 and then at 100. I get the same result in both cases. When I add a line break between first and last name, last name goes "off-screen".
What is the correct way to implement this kind of layout, such that the ListTile expands only as much as it needs to for the provided content?
Below is the code I tried to make this work.
Notice this line here:
bool isNameShown = false;
. Use this to toggle the state for the error case.
This is a working standalone that can be copied into a new .dart file and run. Thank you for taking a look.
import 'package:flutter/material.dart';
void main() => runApp(AvatarChatListDemo());
class AvatarChatListDemo extends StatefulWidget {
@override
_AvatarChatListDemoState createState() => _AvatarChatListDemoState();
}
class _AvatarChatListDemoState extends State<AvatarChatListDemo> {
var imagePath = 'assets/images/lion.jpeg';
List chatHistory = ['Hello there Sam', 'Hi Bob, Good day '];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(appBar: null, body: getChatMessageList()));
}
Widget getChatMessageList() {
bool isNameShown = true; // Use this to toggle the state for the error case.
return ListView.builder(
itemCount: chatHistory.length,
itemBuilder: (BuildContext context, int index) {
return getNextChatListTile(index, isNameShown);
},
);
}
double dim = 100;
ListTile getNextChatListTile(int chatMessageIndex, bool isNameShown) {
var chatMessage = chatHistory[chatMessageIndex];
Image leftSideAvatarImage =
Image.asset(imagePath, width: dim, height: dim, fit: BoxFit.cover);
List<Widget> columnWidgets = [
Expanded(child: leftSideAvatarImage),
];
if (isNameShown) {
columnWidgets.add(Expanded(
child: Text('Matt Houston',
style: TextStyle(color: Colors.green, fontSize: 20))));
}
Column leftSideAvatarColumn = Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: columnWidgets);
Container messageContainer = Container(
padding: EdgeInsets.all(15),
color: Colors.white,
child: Text(chatMessage, style: TextStyle(fontSize: 20)));
return ListTile(
contentPadding: EdgeInsets.all(5),
leading: leftSideAvatarColumn,
title: messageContainer);
}
}