Everything expands to screenwidth inside a Listview. Can I change that?
You can use Align
widget to align it's child inside it's parent.
Simply wrap your list nodes (Card instances) inside a Align
.
import 'package:flutter/material.dart';
//import '../../Library/Library.dart';
//import '../../Ui/ChatMessage.dart';
void main() {
runApp(
new MaterialApp(
home: new ChatScreen(),
),
);
}
class ChatScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new ChatScreenState();
}
}
class ChatScreenState extends State<ChatScreen> {
bool overlayShouldBeVisible = false;
@override
Widget build(BuildContext context) {
return new Scaffold(body: new ListView.builder(
itemBuilder: (context, index) {
return new Align(
alignment: index.isEven ? Alignment.centerLeft : Alignment.centerRight,
child: new Card(
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: new Text("Hello World $index"),
),
),
);
},
));
}
}
I have done a little bit of refactor on your code an here is the result:
Basically I keep a flag for the type of message (sent or received) and align the message card accordingly
Note I did not have the time to review the code but I noticed a lot of unnecessary nesting so you may want to revise the layout a little bit
class ChatScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new ChatScreenState();
}
}
class ChatMessage extends StatelessWidget {
String type;
ChatMessage({this.type});
@override
Widget build(BuildContext context) {
return new Row(
mainAxisAlignment:
this.type == "sent" ? MainAxisAlignment.end : MainAxisAlignment.start,
children: <Widget>[
new Card(
color: Colors.green,
child: new Padding(
padding: new EdgeInsets.all(7.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Text('Message'),
new Text('17:00'),
],
),
),
),
],
);
}
}
class ChatScreenState extends State<ChatScreen> {
bool overlayShouldBeVisible = false;
@override
Widget build(BuildContext context) {
return new Stack(
fit: StackFit.expand,
children: <Widget>[
new Scaffold(
appBar: new AppBar(
title: new Text(
'Chatroom name',
style: new TextStyle(
color: Colors.black,
),
),
centerTitle: true,
backgroundColor: Colors.white,
elevation: 0.0,
),
body: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Expanded(
child: new Container(
decoration: new BoxDecoration(
//image: new DecorationImage(image: new AssetImage('assets/backgroundChat.jpg',),fit: BoxFit.cover)
),
child: new ListView(
children: <Widget>[
new ChatMessage(
type: "sent",
),
new ChatMessage(
type: "sent",
),
new ChatMessage(
type: "received",
),
new ChatMessage(
type: "sent",
),
new ChatMessage(
type: "received",
),
new ChatMessage(
type: "received",
),
],
),
),
),
new Container(
height: 50.0,
color: Colors.white,
child: new Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Expanded(
child: new Padding(
padding: new EdgeInsets.only(left: 20.0),
child: new TextField(),
),
),
new Material(
color: Colors.white,
child: new InkWell(
child: new Padding(
padding: new EdgeInsets.symmetric(horizontal: 20.0),
child: new Icon(
Icons.send,
color: Colors.blue,
),
),
onTap: () => print('send'),
),
),
],
),
),
],
),
),
//overlayShouldBeVisible == true ? new JsonLoader(): new Container(),
//Library.debugMode ? new DebugOverlay(): new Container(),
],
);
}
}
or as Rémi suggested you can just use Align
instead of Row
like so:
return new Align(
alignment:this.type!="sent"? FractionalOffset.centerLeft:FractionalOffset.centerRight,
child:
new Card(
..
I know this is a bit late but this may be the easiest solution. I don't know if this is a good practice or not (you may comment below if it is not).
What I did is I wrapped the message (I mean the widget that contains the message) into a row and added a Spacer()
widget at first or in last depending upon whether the message is on right side or on left
So the code might look something like (The code below is for message on the left side)
Row(
children: [
Card(
color: Colors.green,
child: new Padding(
padding: new EdgeInsets.all(7.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Text('Message'),
new Text('17:00'),
],
),
),
)
Spacer(),
]
)