Reputation: 2406
My application requires a horizontal listview where items can be tapped on.
Rough Layout description below
Container
|_ Stack
|_ (background content)
|_ Column (overlay, align end vertically)
|_ Expand (fill up space above)
|_ ListView (horizontal)
|_ SizedBox (padding)
Problem
When inserting this ListView (or uncommenting), Flutter throws a fit with the following error:
======== Exception caught by rendering library =====================================================
The following assertion was thrown during performLayout():
'package:flutter/src/rendering/viewport.dart': Failed assertion: line 1852 pos 16: 'constraints.hasBoundedHeight': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
The relevant error-causing widget was:
ListView file:///C:/Users/CybeX/CozyUp/cozyup-mobile-flutter/lib/ui/components/ui_component_partner_selector.dart:76:13
When the exception was thrown, this was the stack:
#2 RenderShrinkWrappingViewport.performLayout (package:flutter/src/rendering/viewport.dart:1852:16)
#3 RenderObject.layout (package:flutter/src/rendering/object.dart:1777:7)
#4 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:113:14)
#5 RenderObject.layout (package:flutter/src/rendering/object.dart:1777:7)
#6 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:113:14)
...
The following RenderObject was being processed when the exception was fired: RenderShrinkWrappingViewport#400d9 relayoutBoundary=up16 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
... needs compositing
... parentData: <none> (can use size)
... constraints: BoxConstraints(0.0<=w<=395.4, 0.0<=h<=Infinity)
... size: MISSING
... axisDirection: right
... crossAxisDirection: down
... offset: ScrollPositionWithSingleContext#72596(offset: 0.0, range: null..null, viewport: null, ScrollableState, ClampingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#601d0, ScrollDirection.idle)
RenderObject: RenderShrinkWrappingViewport#400d9 relayoutBoundary=up16 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I tried wrapping the ListView
in an Expanded
but this recentered it in the middle of the screen as suggested here. I tried adding an Expanded top as suggested here, but Flutter doesn't like this.
fwiw, tried ShrinkWrap too (wasn't really expecting much here - didn't help either)
MVCE
import 'package:flutter/material.dart';
void main() async {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
List<String> imgSrc = [
"https://randomuser.me/api/portraits/women/84.jpg",
"https://randomuser.me/api/portraits/men/82.jpg",
"https://randomuser.me/api/portraits/women/11.jpg",
"https://randomuser.me/api/portraits/women/61.jpg",
"https://randomuser.me/api/portraits/men/1.jpg",
];
List<Widget> _listviewItems() {
return imgSrc
.map((e) => Image.network(e))
.map((e) => Image(
image: e.image,
fit: BoxFit.scaleDown,
width: 64,
))
.toList();
}
Widget w = Container(
child: Stack(
children: [
// Center(
// child: cards.first,
// ),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.all(0.0),
scrollDirection: Axis.horizontal,
children: _listviewItems(),
)),
SizedBox(
height: 8,
)
],
)
],
));
return Scaffold(
body: Container(width: double.infinity, child: w),
);
}
}
Image above is with ListView
wrapped in Expanded
, i.e.
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: Container()
),
ListView(
padding: const EdgeInsets.all(0.0),
scrollDirection: Axis.horizontal,
children: _listviewItems(),
),
SizedBox(
height: 8,
)
],
)
Question:
How can I align a horizontal listview to the bottom of the screen allowing for horizontal scrolling (as shown in the image above)?
fyi: I added shrinkWrap: true
and wrapped the Column
(inside the Stack) inside of an Extended
(as suggested here) resulting in an error that leads me here which suggests the opposite - quite frustrating!
Upvotes: 0
Views: 2251
Reputation: 54407
You can copy paste run 2 full code below
Solution 1: You can use bottomSheet
code snippet
return Scaffold(
appBar: ...
body: ...
bottomSheet: SizedBox(height: 64, child: listview()),
);
Solution 2: Wrap ListView
with Align
and SizedBox
code snippet
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 64,
child: ListView(
padding: const EdgeInsets.all(0.0),
scrollDirection: Axis.horizontal,
children: _listviewItems(),
),
working demo
full code of solution 1
import 'package:flutter/material.dart';
void main() async {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
List<String> imgSrc = [
"https://randomuser.me/api/portraits/women/84.jpg",
"https://randomuser.me/api/portraits/men/82.jpg",
"https://randomuser.me/api/portraits/women/11.jpg",
"https://randomuser.me/api/portraits/women/61.jpg",
"https://randomuser.me/api/portraits/men/1.jpg",
"https://randomuser.me/api/portraits/men/2.jpg",
"https://randomuser.me/api/portraits/men/3.jpg",
"https://randomuser.me/api/portraits/men/4.jpg",
"https://randomuser.me/api/portraits/men/5.jpg",
"https://randomuser.me/api/portraits/men/6.jpg",
"https://randomuser.me/api/portraits/men/7.jpg",
];
Widget listview() {
List<Widget> imgList = imgSrc
.map((e) => Image.network(e))
.map((e) => Image(
image: e.image,
fit: BoxFit.scaleDown,
width: 64,
))
.toList();
return ListView(
scrollDirection: Axis.horizontal,
children: imgList,
);
}
return Scaffold(
appBar: AppBar(title: const Text('AppBar Demo')),
body: Center(
child: Container(
//width: double.infinity,
child: Text("other content")),
),
bottomSheet: SizedBox(height: 64, child: listview()),
);
}
}
full code of solution 2
import 'package:flutter/material.dart';
void main() async {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
List<String> imgSrc = [
"https://randomuser.me/api/portraits/women/84.jpg",
"https://randomuser.me/api/portraits/men/82.jpg",
"https://randomuser.me/api/portraits/women/11.jpg",
"https://randomuser.me/api/portraits/women/61.jpg",
"https://randomuser.me/api/portraits/men/1.jpg",
"https://randomuser.me/api/portraits/men/2.jpg",
"https://randomuser.me/api/portraits/men/3.jpg",
"https://randomuser.me/api/portraits/men/4.jpg",
"https://randomuser.me/api/portraits/men/5.jpg",
"https://randomuser.me/api/portraits/men/6.jpg",
"https://randomuser.me/api/portraits/men/7.jpg",
];
List<Widget> _listviewItems() {
return imgSrc
.map((e) => Image.network(e))
.map((e) => Image(
image: e.image,
fit: BoxFit.scaleDown,
width: 64,
))
.toList();
}
Widget w = Container(
child: Stack(
children: [
// Center(
// child: cards.first,
// ),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 64,
child: ListView(
padding: const EdgeInsets.all(0.0),
scrollDirection: Axis.horizontal,
children: _listviewItems(),
),
),
)),
SizedBox(
height: 8,
)
],
)
],
));
return Scaffold(
body: Container(width: double.infinity, child: w),
);
}
}
Upvotes: 0
Reputation: 716
wrap your list view with container and give height to container like this
Container(
height:50,
ListView(
padding: const EdgeInsets.all(0.0),
scrollDirection: Axis.horizontal,
children: _listviewItems(),
),
),
Upvotes: 0