ListView inside Stack Inside SingleChildScrollView - flutter

I need to scroll the whole screen, i am using (single child scroll view => stack => ListView.builder). but there is no scrolling. however i am using:
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
The Code Is:
return Scaffold(
body: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Container(
height: constraints.maxHeight,
child: Stack(children: <Widget>[
Container(color: Colors.red,height: 300,),
Container(
margin: EdgeInsets.only(
top: screen.isPhone ? 150 : 240,
),
child: Column(
children: [
Card(
elevation: 5,
child: ListView.builder(
itemCount: 20,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) =>
ProductItemWidget(showDeleteIconButton: true),
),
),
Text("HEY"),
],
),
),

remove height: constraints.maxHeight,

Related

Vertical is working but horizontal does not work

I want to add a listview in Card widget. It works when scroll vertically, but not when scroll horizontally. How can I fix it? It is in Sizedbox. I tried flexible and expanded but doesnt work.
return Scaffold(
appBar: appBar(),
body: Padding(
padding: const EdgeInsets.only(top: 5, left: 8, right: 5),
child: Column(
children: [
Card(
elevation: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 100,
width: 110,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: 5,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: TextButton(onPressed: () {}, child: Text(brandName[index])),
);
},),),)],),),],),),);
Do this instead:
/*...*/
SizedBox(
height: 100,
width: 110,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: 5,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
width: // set a value,
child: ListTile(
// for suggestion you don't need `TextButton` here
// just do `title: Text(brandName[index])` and use the `onTap` function of `ListTile` instead
title: TextButton(
onPressed: () {},
child: Text(brandName[index])
)
),
);
},
),
)
/*...*/
Wrap your ListTile with SizedBox() and explicitly specify the width of ListTile.
eg. SizedBox (width: 100, LisTile(...))
For better understanding refer this answer.

Nesting 2 ListViewBuilder in a SingleScrollView let the app freezing

I need 2 different lists in a scrollable view, so i did the following:
body:SingleChildScrollView(
physics: const ScrollPhysics(),
child: Column(
children: <Widget>[
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context,index){
return Container(
padding: const EdgeInsets.all(10),
height: 75,
child: Row(
children: <Widget>[
],
),
);
}
),
ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context,index){
return Container(
padding: const EdgeInsets.all(10),
height: 75,
child: Row(
children: <Widget>[
],
),
);
}
),
]
),
),
If i press the button to open this ListView nothing happens and the app is frezzed.
Any idea ?
Let me know if you need more information,
Thanks

Using both horizontal and vertical listview.builder on a page in flutter

In my application, I want to show two different products on the home screen, horizontally and vertically. But I want to do this with ListView.Builder as they both come as lists. I couldn't find the right usage of this, can you help with this?
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 200.0,
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 25,
itemBuilder: (BuildContext context, int index) =>
Card(
child: Center(child: Text('Horizontal List Child')),
),
),
),
ListView.builder(
itemCount: 10,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Expanded(
child: Card(
child:
Center(child: Text('Vertical List Child'))),
);
},
)
],
),
),
I can do it without using ListView.builder but I need to use ListView.builder. The height of the vertical part should be equal to the element inside.
You must need to define the height of any scroll view. I prefer the horizontal scroll view
SingleChildScrollView(
child: Column(
children: [
Container(
height: 150,
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
...
...
...
},
),
),
ListView.builder(
itemCount: 10,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
...
...
...
},
),
],
)
)
Remove the SingleChildScrollView.
Add an Expanded as parent to the second ListView.
Remove the Expanded from the Card
Scaffold(
body: SafeArea( //in case you dont have appbar
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: [
const SliverToBoxAdaptar(child:Container(child:ListView(...)))// horizontalList
const SliverList()// verticalSliverList
],
),
),
);
try thiss
Expanded makes item inside becomes full body.
just remove it and the height to make item height equals to card
return Scaffold(
appBar: AppBar(
title: Text("Sample"),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: SingleChildScrollView(
physics: ScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Sample 1"),
),
Container(
height: 100,
child: ListView.builder(
physics: ScrollPhysics(),
itemCount: 5,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Card(
child: Image.network("https://i.picsum.photos/id/9/250/250.jpg?hmac=tqDH5wEWHDN76mBIWEPzg1in6egMl49qZeguSaH9_VI",),
);
}
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Sample 2"),
),
ListView.builder(
physics: ScrollPhysics(),
itemCount: 5,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card(
child: Image.network("https://i.picsum.photos/id/9/250/250.jpg?hmac=tqDH5wEWHDN76mBIWEPzg1in6egMl49qZeguSaH9_VI"),
);
}
),
],
),
),
),
);

How to use Listview in SingleChildScrollView in flutter?

I need to use 3 horizontal ListView in the SingleChildScrollView widget. But nothing is displayed. I use these codes for one of ListViews:
Scaffold(
body: new SingleChildScrollView(
primary: true,
child: new Column(
mainAxisSize: MainAxisSize.min,
children: [
new ListView.builder(
primary: false,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: _categoryModel.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => new Card(
child: new Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
child: new Text(_categoryModel[index].title),
),
),
))
],
),
))
How can I fix this error without using the container with a height?
try wrapping your ListView with Expanded
Use Wrap widget instead of ListView.
Use This :
Scaffold(
body: new SingleChildScrollView(
child: new Container(
child: new ListView.builder(
primary: false,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: _categoryModel.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => new Card(
child: new Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
child: new Text(_categoryModel[index].title),
),
),
))
),
))

Provide some extra space at the end of ListView.builder

Below is my code, I want to add some extra space of height 50, which comes at the end of list item. because when my second child of stack appears it nearly overlaps the last item of list view. I've tried wrapping ListView.builder with column and added a container at last but destroyed my whole structure. for this scenario I've to wrap the column into Single scrollable which pushed stack 2nd widget to be at the end of ListItem.(But I don't want Stack 2nd object to be scrollable).
As you can see I'm not able to click on HotDog.
body: Stack(
children: <Widget>[
ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
return Text(data[index].name);
}
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.cyan
),
padding: EdgeInsets.all(10),
height: 60,
),
)
],
),
How about you add empty last item like below code?
ListView.builder(
itemCount: itemData.length + 1,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
if (index == item.Data.length) {
return SizedBox(height: 50);
} else {
return Text(data[index].name);
}
}
),
ListViewBuilder should be wrap inside Expanded widget which will take fullscreen
and give container bottom width as per need.
Example:
var itemData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Stack(
children: <Widget>[
Column(
children: <Widget>[
Expanded(
child: Container(
margin: EdgeInsets.only(bottom: 20),
child: ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 80,
child: Text("Text :" + index.toString()));
}),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.cyan),
padding: EdgeInsets.all(10),
height: 60,
),
),
)
],
),
],
),
Output:
This can be easily done by adding bottom padding in listview.builder
Expanded(
child: ListView.builder(
padding: EdgeInsets.only(bottom: 100), //Increase this as per your requirment
itemCount: 5,
itemBuilder: (cxt , idx) {
return YourWidget();
}
Since you're listview.builder is inside a stack, you simply use the Positioned widget for this. Simply wrap your listview with Positioned like below:
Positioned(
bottom:50, //adjust this since this is the padding inside the stack
child:Container(
width:MediaQuery.of(context).size.width //width of the whole phone
child: ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
return Text(data[index].name);
}
),
),
),
To ensure your Container stays at the bottom wrap it with a positioned widget and set the bottom property to 0:
Positioned(
bottom:0, //adjust this since this is the padding inside the stack
child:Container(),
),
Here is a one minute clip showing how to use the Positioned widget: https://www.youtube.com/watch?v=EgtPleVwxBQ
There is no specific way to do it by default you have to do it manually with own logic
ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
if(index == itemData.length - 1 )
return Padding(
padding: EdgeInsets.only(bottom : 50),
child : Text(data[index].name)
);
return Text(data[index].name);
}),