Scrollable HomeScreen in Flutter - flutter

I wonder why that doesn't work. Maybe one can help me, I think it's just a small mistake.
I would like to be able to scroll the whole screen. The container with the "CompanyCard" widget can be scrolled vertically.
return Column(
children: <Widget>[
SearchBox(),
Expanded(
child: Stack(
children: <Widget>[
Container(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: companies.length,
itemBuilder: (context, index) => CompanyCard(),
),
),
],
),
),
SearchBox(),
SearchBox(),
SearchBox(),
],
);
horizontal: Facebook, Google Twitter (already works)
vertical: the whole screen (not working)

Wrap SingleChildScrollView to the widgets you like to scroll
return Column(
children: <Widget>[
SearchBox(),
SingleChildScrollView(
child: Expanded(
child: Stack(
children: <Widget>[
Container(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: companies.length,
itemBuilder: (context, index) => CompanyCard(),
),
),
],
),
),
),
SearchBox(),
SearchBox(),
SearchBox(),
],
);
New edit:
To make the whole page scrollable, wrap the page in SingleChildScrollView:
Full Code:
return Container(
child: SingleChildScrollView(
child: Expanded(
child: Column(
children: <Widget>[
SearchBox(),
SingleChildScrollView(
child: Expanded(
child: Stack(
children: <Widget>[
Container(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: companies.length,
itemBuilder: (context, index) =>
CompanyCard(),
),
),
],
),
),
),
SearchBox(),
SearchBox(),
SearchBox(),
],
),
),
),
);

You need to specify an explicit height to your List View. By default a List View has infinite height / width.
To be able to scroll the entire screen, you need to wrap your root widget inside a SingleChildScrollView and then specify a height for the List View container. Somewhat like this :-
body : SingleChildScrollView(child :...
... Other widgets...
Container (
height :200,
width :MediaQuery.of(context).size.width, // so that ListView occupies the entire width
child : ListView.builder(...

I think ListView in Column needs height.
I wrapped ListView with Container and give a some height.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("Home page"),
elevation: 5.0,
),
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
SizedBox(child: Text('asdf')),
Container(
height: 500,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 3,
itemBuilder: (context, index) =>
SizedBox(width: 200, child: Text('aaa')),
),
),
SizedBox(child: Text('asdf')),
SizedBox(child: Text('asdf')),
SizedBox(child: Text('asdf')),
],
),
),
),
);
}

Related

How to use listview with other widgets?

I want to use ListView with other widgets , but I can't. When I use container for Listview, I can't view any other widgets. How can I do it?
Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(),
RaisedButton(
child: Text('Text'),
onPressed:(){})
])));
You shouldn't nest scroll views at all if you are trying to show some widgets based on a list, dart lets you use for inside any collection also you can use List.generate, or list.map with the spread operator
Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
for(final item in list) widget,
RaisedButton(child: Text('Text'), onPressed: () {})
],
),
),
);
or
Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
...list.map((item)=> widget).toList(),
RaisedButton(child: Text('Text'), onPressed: () {})
],
),
),
);
or
Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
...List.generate(list.length, (index)=> widget).toList(),
RaisedButton(child: Text('Text'), onPressed: () {})
],
),
),
);
This is because you are using ListView inside Column, both ListView and Column take the full screen available to them, as this way we can only see ListView on the screen, to resolve this we have to shrink ListView to its exact size, for it shrinkwrap: true is used.
ListView.Builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
)
physics: NeverScrollableScrollPhysics(), is used here to stop ListView scrolling, you have added SingleChildScrollView() which scroll entire page
Add ShrinkWrap to The ListView
Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
ListView(
shrinkWrap: true,
children:[
Container(),
Container(),
]
),
RaisedButton(
child: Text('Text'),
onPressed:(){})
])));
for More Advanced Scrolling Challenges like More than One ListView in Column I Suggest you add a ScrollPhysics
u need use Expanded here and set data to ListView.builder
final items = List<String>.generate(10000, (i) => 'Item $i');
Column(children: [
Expanded(
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
);
},
),
AnyWidget(...)
])
You have to wrap your ListView widget with Expanded or if you want to wrap it with Container then you must have to give Container height or width
Try this Code...
Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemCount: 4,
shrinkWrap: true,
itemBuilder: (context, index) {
return Text('Hello');
}
),
RaisedButton(
child: Text('Text'),
onPressed: () {}
)
]
)
)
);
In this example, the ListView and the other widget (a Container with yellow color) are both children of the Column widget. By doing this, you can ensure that the ListView and the other widgets can both be displayed on the screen.
Column(
children: <Widget>[
Container(
height: 200,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 160.0,
color: Colors.red,
),
Container(
width: 160.0,
color: Colors.blue,
),
Container(
width: 160.0,
color: Colors.green,
),
],
),
),
Container(
height: 200,
color: Colors.yellow,
),
],
)

Flutter SingleChildScrollView not scrolling

My singleChildScollView won't scroll vertically. I've checked similar questions regarding this problem but none of them sem to work for me.
The page fills up with the items, and the homepage button is placed at the bottom...
...so it looks correct, it just doesn't let me scroll.
Can anyone help? [ EDIT - please note in the example code below I have simplified the original widget tree and removed the homepage button]...
Scaffold(
body: SingleChildScrollView(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (ctx, index) {
...list of items here...
}
),
),
)
There is two steps you can do to use SingleChildScrollView in a Column widget
Wrap it in a SizedBox
Set a height to the SizedBox widget
Try this out :
Scaffold(
body:
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
//set a height
height : MediaQuery.of(context).size.height/5,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (ctx, index) {
...list of items here...
}
),
],
),
),
),
Center(
child: ElevatedButton(
onPressed: () {Navigator.pop(context);},
child: Text('Homepage'),
),
),
],
),
)
#james please check it
Scaffold(
body: Stack(
children: [
SingleChildScrollView(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: 30,
itemBuilder: (ctx, index) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Text("index $index"),
);
}
),
),
Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
onPressed: () {Navigator.pop(context);},
child: Text('Homepage'),
),
),
],
),
)
thanks for the help, expecially #Jahidul Islam.
I was missing the physics: ScrollPhysics() line!
In order for the SingleChildScrollView to work, its parent's height should be defined.
You can achieve this by wrapping the SingleChildScrollView in a Container/SizedBox, or by wrapping it with the Expanded widget.

How to put a shadow above containers inside ListView.builder Flutter?

I have a ListView.builder where I want to show containers with shadows. And I want a shadow of one container to cover another container. Example of how it should looks.
It easily to do with Stack widget, but I have no idea how to do it inside ListView.builder.
Solution that works fine for me
Instead of using ListView I've decided to use CustomScrollView that takes slivers as parameters. Inside slivers I'm maping through a list of items and return my container wrapped with SliverToBoxAdapter. I don't know exactly how it works, but it works fine for me.
CustomScrollView(
slivers: [
...names.map(
(e) => SliverToBoxAdapter(
child: Center(
child: CustomContainer(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Container #${e['name']}'),
Text('Age is ${e['age']} y.o.')
],
),
),
),
),
),
),
],
),
// if scroll view overflow on other widget then use ClipRRect With Expanded.
ClipRRect(
child: Expanded(
child: CustomScrollView(
clipBehavior: Clip.none, //add this line inside CustomScrollView
slivers: [
...names.map(
(e) => SliverToBoxAdapter(
child: Center(
child: CustomContainer(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Container #${e['name']}'),
Text('Age is ${e['age']} y.o.')
],
),
),
),
),
),
),
],
),),),
I face the same problem and i use this tricks and it's solved.
You can use index of listview and give different elevation of card according to index.
ListView.builder(
itemCount:10,
shrinkWrap: true,
itemBuilder: (ctx, i) {
return Card(
elevation: (i%2 == 1)?10 :0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment:CrossAxisAlignment.center,
mainAxisAlignment:MainAxisAlignment.center,
children: [
Text("Container $i"),
],
),
),
);
}),

How can I add a button above a list?

I tried to add a RaisedButton above the ListView. I used a Colum but I got an error. Can anybody tell me where my mistake is? Thanks in advance!
body: Column(
children: <Widget>[
RaisedButton(
child: Text("Test"),
onPressed: null,
),
ListView.builder(
itemCount: exercises.length,
itemBuilder: (context, i) {
return Container(
child: Text(
exercises[i]["text"],
),
);
},
),
],
),
Adding to #Viren answer, You should use Flexible instead of Expanded
body: Column(
children: <Widget>[
RaisedButton(
child: Text("Test"),
onPressed: null,
),
Flexible(
child: Container(
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, i) {
return Container(
child: Text(
'jitesh',
),
);
},
),
),
)
],
),
Please find diff Flutter: Expanded vs Flexible
You need to wrap your listview with Expanded widget.
body: Column(
children: <Widget>[
RaisedButton(
child: Text("Test"),
onPressed: null,
),
Expanded( // added widget
child: ListView.builder(
itemCount: exercises.length,
itemBuilder: (context, i) {
return Container(
child: Text(
exercises[i]["text"],
),
);
},
),
],
),
)

How to put Expandable list view inside scroll view in flutter?

Hello there i am making a flutter application in which inside ScrollView in need to put Expandable list view.First of all here is my build method.
return Scaffold(
appBar: AppBar(
backgroundColor: app_color,
iconTheme: IconThemeData(
color: Colors.white, //change your color here
)),
//debugShowCheckedModeBanner: false,
//key: scaffoldKey,
backgroundColor: app_color,
body: SingleChildScrollView(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:<Widget>[
Text("Header"),
new ListView.builder(
itemCount: datas.length,
shrinkWrap: true,
itemBuilder: (context, i) {
return new ExpansionTile(
title: new Text(datas[i].title, style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic),),
children: <Widget>[
new Column(
children: _buildExpandableContent(datas[i]),
),
],
);
},
),
Text("Footer"),
],
),
)
)
);
}
Now the problem is that without SingleScrollChidView this works fine But after using SingleScrollChidView it does not shows anything and gives error RenderBox was not laid out.What is wrong here ? How can i use Expandable list view inside Singlechildscroll view in flutter.
I was able to achieve Expanded ListView within ScrollView with text by
- Use of Wrap inside SingleChildScrollView, provided you make all ListView using shrinkWrap: true
SingleChildScrollView(
child: Wrap(
direction: Axis.horizontal,
children: <Widget>[
_textBody, // text body, with 1000+ words
Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
ListViewOne(_genericListDataOne()),
],
),
),
Column(
children: <Widget>[
ListViewTwo(_genericListDataTwo())
],
)
],
),
),
part of the Code for ListViewOne
ListViewOne(
shrinkWrap: true,
padding: new EdgeInsets.symmetric(vertical: 8.0),
children: // build list here,
);
Give your ListView a fixed height using SizedBox or similar
SingleChildScrollView(
child: Column(
children: <Widget>[
Text("Header"),// tested with 20 of these for scrolling
SizedBox(
height: MediaQuery.of(context).size.height / 2,
child: new ListView.builder(
itemCount: 20,
shrinkWrap: true,
itemBuilder: (context, i) {
return new ExpansionTile(/* whatever */ );
},
),
),
Text("Footer"),// tested with 20 of these for scrolling
],
),
)
Use SizedBox.expand for this problem,
SizedBox.expand(
child : ListView.builder(
itemCount: datas.length,
shrinkWrap: true,
itemBuilder: (context, i) {
return new ExpansionTile(
title: new Text(datas[i].title, style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic),),
children: <Widget>[
new Column(
children: _buildExpandableContent(datas[i]),
),
],
);
},
),
);
Edited answer
Try this, you should get the desired output you are looking for.
You can find the output here.
Column(
children: <Widget>[
Text(),
ListView(
shrinkWrap: true,
physics: ScrollPhysics(),
children:[]),
Text()
]
)
adding below shown code in ListView will allow smooth scrolling of widget
shrinkWrap: true,
physics: ScrollPhysics(),