Reputation: 5905
I have a working page that is a dynamic listview of messages using a Listview.builder. The itembuilder calls a widget that creates the card. What I am trying to do is change the first list to be a divider that will be a date and then will call a list of items by that date. All the data calls and lists are being created but keep getting hasSize is not true errors and can not see where the size is a problem, I just used the same layouts that were working.
Not sure what code to show to get some assistance, so let me know if you have ideas and what code you might need to see.
This is the start that worked prior to change:
var _children = <Widget>[
new Expanded(
child: new RefreshIndicator(
child: new ListView.builder(
itemBuilder: _divBuilder,
itemCount: listcount,
),
onRefresh: _onRefresh,
),
),
new Stack(
alignment: Alignment.centerRight,
children: <Widget>[
new TextField(
decoration: const InputDecoration(
hintText: 'Chat Reply',
labelText: 'Chat Reply:',
),
autofocus: false,
focusNode: _focusnode,
maxLines: 2,
controller: _newreplycontroller,
keyboardType: TextInputType.url,
),
new IconButton(
icon: new Icon(Icons.send),
onPressed: _sendReply,
alignment: Alignment.centerRight,
)
],
),
];
return new Scaffold(
appBar: new AppBar(
title: mytitle,
actions: getAppBarActions(context),
),
body: new Column(
mainAxisSize: MainAxisSize.max,
children: _children,
),
);
Now I have 2 widgets that are being used.
class MyChatWidget extends StatefulWidget {
MyChatWidget({Key key, this.datediv, this.msgkey}) : super(key: key);
final DateTime datediv;
final String msgkey;
@override
_MyChatWidgetState createState() => new _MyChatWidgetState();
}
class _MyChatWidgetState extends State<MyChatWidget> {
List messagelist;
int messagecount = 0;
var jsonCodec = const JsonCodec();
_getMessages() async {
var _url = 'http://$baseurl/csapi/messages/getbydate';
DateChatMessage dcm = new DateChatMessage(widget.msgkey, widget.datediv.toString());
var json = jsonCodec.encode(dcm);
var http = createHttpClient();
var response = await http.post(_url, headers: getAuthHeader(), body: json);
var messages = await jsonCodec.decode(response.body);
if (mounted) {
setState(() {
messagelist = messages.toList();
messagecount = messagelist.length;
//replysub = 'Re: ' + chatlist[0]['sub'];
});
}
}
@override
void initState() {
super.initState();
//controller = new TabController(length: 4, vsync: this);
_getMessages();
}
@override
Widget build(BuildContext context) {
var _children = <Widget>[
new Divider(height: 5.0,color: Colors.red,),
new Expanded(
child: new ListView.builder(
itemBuilder: _itemBuilder,
itemCount: messagecount,
),
),
];
return new Column(
mainAxisSize: MainAxisSize.min,
children: _children,
);
}
Widget _itemBuilder(BuildContext context, int index) {
ChatMessage mychat = getChat(index);
return new ChatWidget(
mychat: mychat,
);
}
ChatMessage getChat(int index) {
//prefs.setInt('pid', myReferralList[index]['pid']);
return new ChatMessage(
messagelist[index]['msgkey'],
messagelist[index]['referralname'],
messagelist[index]['sub'],
messagelist[index]['oid'],
messagelist[index]['oname'],
messagelist[index]['pid'],
messagelist[index]['pname'],
messagelist[index]['sender'],
messagelist[index]['sendname'],
messagelist[index]['receiver'],
messagelist[index]['receivename'],
messagelist[index]['message'],
messagelist[index]['submitdate'],
messagelist[index]['pgrpid'],
messagelist[index]['prid'],
messagelist[index]['fcmtoken'],
);
}
}
class ChatWidget extends StatefulWidget {
ChatWidget({Key key, this.mychat}) : super(key: key);
final ChatMessage mychat;
@override
_ChatWidgetState createState() => new _ChatWidgetState();
}
class _ChatWidgetState extends State<ChatWidget> {
@override
Widget build(BuildContext context) {
DateTime submitdate = DateTime.parse(widget.mychat.submitdate).toLocal();
return new Card(
child: new Container(
width: 150.0,
padding: new EdgeInsets.all(10.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Row(
children: <Widget>[
new Text(
widget.mychat.sendname,
style: new TextStyle(
fontSize: 15.0, fontWeight: FontWeight.bold),
),
new Text(' @ '),
new Text(new DateFormat.yMd().add_Hm().format(submitdate)),
//new Text(submitdate.toLocal().toString())
],
),
//new Text(widget.mychat.receivename,style: new TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),),
//new Text(new DateFormat.yMd().add_Hm().format(submitdate)),
new Text('${widget.mychat.message}'),
],
),
),
);
/*return new ListTile(
leading: new CircleAvatar(child: new Text(widget.mychat.oname[0])),
title: new Text(widget.mychat.referralname),
subtitle: new Text(new DateFormat.yMd().add_Hm().format(submitdate)),
trailing: new Text(widget.mychat.sendname),
onTap: _onTap,
);*/
}
void _onTap() {
Route route = new MaterialPageRoute(
settings: new RouteSettings(name: "/chats/chatconvodetil"),
builder: (BuildContext context) =>
new ChatConvoDetail(mychat: widget.mychat),
);
Navigator.of(context).push(route);
}
}
Any guidance would be great
Full Error Stack
══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY
╞═════════════════════════════════════════════════════════
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
When a column is in a parent that does not provide a finite height constraint, for example if it is
in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
space in the vertical direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
cannot simultaneously expand to fit its parent.
Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
themselves to less than the infinite remaining space they would otherwise be forced to take, and
then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
constraints provided by the parent.
The affected RenderFlex is:
RenderFlex#d88d8 relayoutBoundary=up8 NEEDS-LAYOUT NEEDS-PAINT
The creator information is set to:
Column ← MyChatWidget ← RepaintBoundary-[<0>] ← NotificationListener<KeepAliveNotification> ←
KeepAlive ← AutomaticKeepAlive ← SliverList ← ShrinkWrappingViewport ← _ScrollableScope ←
IgnorePointer-[GlobalKey#ac8f6] ← Listener ← _GestureSemantics ← ⋯
See also: https://flutter.io/layout/
https://flutter.io/debugging/#rendering-layer
http://docs.flutter.io/flutter/rendering/debugDumpRenderTree.html
If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
https://github.com/flutter/flutter/issues/new
When the exception was thrown, this was the stack:
The following RenderObject was being processed when the exception was fired:
RenderFlex#d88d8 relayoutBoundary=up8 NEEDS-LAYOUT NEEDS-PAINT
creator: Column ← MyChatWidget ← RepaintBoundary-[<0>] ←
NotificationListener<KeepAliveNotification> ← KeepAlive ← AutomaticKeepAlive ← SliverList ←
ShrinkWrappingViewport ← _ScrollableScope ← IgnorePointer-[GlobalKey#ac8f6] ← Listener ←
_GestureSemantics ← ⋯
size: MISSING
direction: vertical
mainAxisAlignment: start
mainAxisSize: min
crossAxisAlignment: center
verticalDirection: down
RenderConstrainedBox#1d682 relayoutBoundary=up9 NEEDS-PAINT
RenderPositionedBox#d9c42 relayoutBoundary=up10 NEEDS-PAINT
RenderPadding#c357c relayoutBoundary=up11 NEEDS-PAINT
RenderConstrainedBox#3ad51 relayoutBoundary=up12 NEEDS-PAINT
RenderDecoratedBox#e68e0 relayoutBoundary=up13 NEEDS-PAINT
RenderSemanticsGestureHandler#83b48 NEEDS-LAYOUT NEEDS-PAINT
RenderPointerListener#9b129 NEEDS-LAYOUT NEEDS-PAINT
RenderIgnorePointer#aa9c2 NEEDS-LAYOUT NEEDS-PAINT
RenderShrinkWrappingViewport#f658c NEEDS-LAYOUT NEEDS-PAINT
RenderSliverList#7b88e NEEDS-LAYOUT NEEDS-PAINT
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: 'package:flutter/src/rendering/box.dart': Failed assertion: line 1433 pos 12: 'hasSize': is not true.
Another exception was thrown: 'package:flutter/src/rendering/sliver_multi_box_adaptor.dart': Failed assertion: line 455 pos 12: 'child.hasSize': is not true.
Upvotes: 4
Views: 12101
Reputation: 53337
'hasSize': is not true
is usually related to having a Column
or Row
with unconstrained size, such that Flutter does not recognize how much space should it render these two widgets in. In your case however, I believe it is caused by your ListView.builder
, try to set shrinkWrap
property in your ListView.builder
to true
and see if it solves your problem, otherwise it is caused by a Column
or a Row
. But I suppose setting shrinkWrap:true
should solve it, so try it first.
After going into further details about the error, it seemed that changing Expanded
to Flexible
have fixed the issue.
Upvotes: 7