How to create scrollable row in flutter - flutter

i tried creating scrollable row in flutter
but after trying multiple methods in some i am facing issue of height being fixed or list is not scrolling
posting one of the code i tried.
looking forward for a way where i can scroll in a row and don't need to fix a height for the widget.
new Column(
children: [
new Container(
height: 100.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
new Text("text 1"),
new Text("text 2"),
new Text("text 3"),
],
),
),
],
),

I have already answered somewhat related question where you don't need to give a fix height to the widgets
and your widgets can scroll in horizontal direction
you can check it here
https://stackoverflow.com/a/51937651/9236994
TIP: Use SingleChildScrollView widget
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: <Widget>[
Text('hi'),
Text('hi'),
Text('hi'),
]
)
)

Replace the Column widget by ListView.
You can take a look at
https://api.flutter.dev/flutter/widgets/ListView-class.html
Regards

Something like this ?
new Column(
children: [
new Container(
height: 100.0,
child: Expanded(
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context,int){
return Container(
child: Row(
children: <Widget>[
new Text("text 1"),
new Text("text 2"),
new Text("text 3"),
],
);
},
),
),
],
),
),
],
),

Related

flutter scrollview and SingleChildScrollView throws bottom overflow and is not scrolling

The widgets inside the child scroll view doesn't scroll and throws bottom overflow exception on the screen when there are more widgets in that list view. I am not sure where I am doing a mistake.
home: Scaffold(
body: Column(
children: [
APPbar(),
Container(
color: Colors.grey[200],
child: Expanded(
child: Column(
children: [
searchBar(),
Row(children: casewidgets),
],
)
),
)
SingleChildScrollView(
child:Column(
children: [
Text("a new column"),
Text("a new column"),
Text("a new column"),
Text("a new column"),
],
)
),
]
)),
You can use Expanded on SingleChildScollView to get aviable height, and remove column's Expanded.
home: Scaffold(
body: Column(children: [
// APPbar(),
Container(
color: Colors.grey[200],
child: Column(
children: [
// searchBar(),
Row(children: []),
],
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
for (int i = 0; i < 33; i++) Text("a new column"),
],
)),
),
])),
You cannot use expand when using a singlechildscrollview in appropriate way. First you need to understand that expand covers the maximum height and width on the screen or the specific section in which you use expand.
Instead of using SingleChildScrollView, It's easier to use CustomScrollView with a SliverFillRemaining. and it's works work's great.
CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
children: <Widget>[
const Text('TextData'),
Expanded(
child: Container(
color: Colors.green,
child: Text("Your Text Data",),
),
),
const Text('Add Other Widgets'),
],
),
),
],
),

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"),
],
),
),
);
}),

Centering layout in Flutter

If I use the following structure in the Scaffold:
body: Container(
alignment: Alignment.center,
child:
Text('Test')
)
Then the text is vertically and centrally structured, as I want. But if I do the following:
body: Container(
alignment: Alignment.center,
child:
ListView(
children:people.map(person).toList(),
),
)
Then the ListView is stuck to the top left of the body and isn't centered.
Why is that, and how can I center the ListView the same way that Text was centered?
Vertical
body: Container(
alignment: Alignment.center,
child:
ListView(
shrinkWrap: true,
children:people.map(person).toList(),
),
)
Horizontal
ListView(
shrinkWrap: true,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('text'),
],
),
Text('text'),
Text('text'),
],
),
It's because ListView take all the space available. To tell Listview to take only children sizes, add property "shrinkWrap" to true.
Center(
child: ListView(
shrinkWrap: true,
children: <Widget>[
Center(
child: Text("Hello world !"),
),
],
),
)

Interact with widget under an image in flutter/dart

I have a question, how do I make a image on top of a listview and still be able to scroll on the listview? Like scroll though the image, so the image is not moving.
When I stack them with 'stack widget' I still can't scroll, only in the parts of the scrollview that dosn't have an image on top of it.
Please help me, this is like a big part of my app that i've been developing for 6 weeks now, and if I can't make it work, my app is kinda done for it!
Here's an example:
Stack(
children: <Widget>[
ListView(
controller: scrollController,
children: <Widget>[
Container(
child: Text('widget 1'),
),
Container(
child: Text('widget 2'),
),
Container(
child: Text('widget 3'),
),
],
),
Image.asset('assets/myImage.png'),
],
),
You can wrap the image with an IgnorePointer widget:
Stack(
children: <Widget>[
ListView(
controller: scrollController,
children: <Widget>[
Container(
child: Text('widget 1'),
),
Container(
child: Text('widget 2'),
),
Container(
child: Text('widget 3'),
),
],
),
IgnorePointer(child: Image.asset('assets/myImage.png')),
],
),

How to add a ListView to a Column in Flutter?

I'm trying to construct a simple login page for my Flutter app. I've successfully built the TextFields and log in/Sign in buttons. I want to add a horizontal ListView. When I run the code my elements disappear, if I do it without the ListView, it's fine again. How can I do this correctly?
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("Login / Signup"),
),
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField(
decoration: new InputDecoration(
hintText: "E M A I L A D D R E S S"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(obscureText: true,
decoration: new InputDecoration(
hintText: "P A S S W O R D"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(decoration: new InputDecoration(
hintText: "U S E R N A M E"
),),
new RaisedButton(onPressed: null,
child: new Text("SIGNUP"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new RaisedButton(onPressed: null,
child: new Text("LOGIN"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new ListView(scrollDirection: Axis.horizontal,
children: <Widget>[
new RaisedButton(onPressed: null,
child: new Text("Facebook"),),
new Padding(padding: new EdgeInsets.all(5.00)),
new RaisedButton(onPressed: null,
child: new Text("Google"),)
],)
],
),
),
margin: new EdgeInsets.all(15.00),
),
),
);
I've got this problem too. My solution is use Expanded widget to expand remain space.
Column(
children: <Widget>[
Expanded(
child: horizontalList,
)
],
);
Reason for error:
Column expands to the maximum size in main axis direction (vertical axis), and so does the ListView.
Solutions:
So, you need to constrain the height of the ListView. There are many ways of doing it, you can choose that best suits your need.
If you want to allow ListView to take up all remaining space inside Column, use Expanded.
Column(
children: <Widget>[
Expanded( // <-- Use Expanded
child: ListView(...),
)
],
)
If you want to limit your ListView to a certain height, use SizedBox.
Column(
children: <Widget>[
SizedBox(
height: 200, // Constrain height.
child: ListView(...),
)
],
)
If your ListView is small, you may try shrinkWrap property on it.
Column(
children: <Widget>[
ListView(
shrinkWrap: true, // Set this
)
],
)
If you want to make ListView to as small as it can be, use Flexible with ListView.shrinkWrap:
Column(
children: <Widget>[
Flexible( // <-- Use Flexible
child: ListView(
shrinkWrap: true, // and set this
),
)
],
)
You can check console output. It prints error:
The following assertion was thrown during performResize():
The horizontal viewport was given unbounded height.
Viewports expand in the cross axis to fill their container and constrain their children to match
their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
vertical space in which to expand.
You need to add a height constraint to your horizontal list. E.g. wrap in Container with height:
Container(
height: 44.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
RaisedButton(
onPressed: null,
child: Text("Facebook"),
),
Padding(padding: EdgeInsets.all(5.00)),
RaisedButton(
onPressed: null,
child: Text("Google"),
)
],
),
)
Expanded Widget increases its size as much as it can with the space available Since ListView essentially has an infinite height it will cause an error.
Column(
children: <Widget>[
Flexible(
child: ListView(...),
)
],
)
Here we should use the Flexible widget as it will only take the space it required as Expanded take full screen even if there are not enough widgets to render on full screen.
I have SingleChildScrollView as a parent, and one Column Widget and then List View Widget as last child.
Adding these properties in List View Worked for me.
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.vertical,
As have been mentioned by others above,Wrap listview with Expanded is the solution.
But when you deal with nested Columns you will also need to limit your ListView to a certain height (faced this problem a lot).
If anyone have another solution please, mention in comment or add answer.
Example
SingleChildScrollView(
child: Column(
children: <Widget>[
Image(image: ),//<< any widgets added
SizedBox(),
Column(
children: <Widget>[
Text('header'), //<< any widgets added
Expanded(child:
ListView.builder(
//here your code
scrollDirection: Axis.horizontal,
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Container();
}
)
),
Divider(),//<< any widgets added
],
),
],
),
);
Actually, when you read docs the ListView should be inside Expanded Widget so it can work.
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Align(
child: PayableWidget(),
),
Expanded(
child: _myListView(context),
)
],
));
}
You can use Flex and Flexible widgets. for example:
Flex(
direction: Axis.vertical,
children: <Widget>[
... other widgets ...
Flexible(
flex: 1,
child: ListView.builder(
itemCount: ...,
itemBuilder: (context, index) {
...
},
),
),
],
);
[Solution Preview] - [List Items are scrollable but heading is fixed]
I have very small & straight forward answer, see putting listview inside column will force column to expand infinitely, which is basically an error thing.
Now if you put physics: NeverScrollableScrollPhysics(), like others suggested, in listview then whats the point of having listview if you disable scrolling inside it..
There is an easy fix, frankly I landed on this by hit and trial. Let me give you small explanation after code.
Column(
children: [
Text(
"All Bookings",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: Colors.brown[700]),
),
Expanded(
child: Container(
margin: EdgeInsets.only(top: 24),
child: ListView.builder(
itemCount: 30,
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text("List Item ${index + 1}"),
),
),
),
),
],
)
I had requirement to have title inside Column as first element & then put a Listview so that user can have scrolling list. This is a generic kind of requirement. You can put this in Bottom Sheet or Modal too.
Code Explanation:
I kept first child as heading inside Column ok (which i donot want to scroll away, i want it to be fixed)
I have Expanded child inside column, which is like acquire all the "remaining space" in column.
Inside that I kept container (Just to put some space between title & list view with margin) this is optional, you can remove container and it will still work.
Now the Listview is well constrained and it won't try to stretch infinitely in column. As Expanded widget already constrained it.
Please correct me if I am wrong anywhere or if this code doesn't work (it works as of now without errors :)
Wrap your Listview with Expanded Widget
Column(
children: <Widget>[
Text('Leading text widget'),
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
ListTile(
leading: Icon(Icons.map),
title: Text('Map'),
),
ListTile(
leading: Icon(Icons.photo_album),
title: Text('Album'),
),
ListTile(
leading: Icon(Icons.phone),
title: Text('Phone'),
),
],
),
Text('More widget'),
],
);
just use
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
properties in listView
You need to do 2 things:
wrap Column inside SingleChildScrollView
add shrinkWrap: true and physics: NeverScrollableScrollPhysics() in ListView
Why it works:
As I uderstand, NeverScrollableScrollPhysics disable scrolling of ListView.
So, scroll works with SingleChildScrollView.
If I am wrong, comment bellow.
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Filter'),
ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: rides.length,
itemBuilder: (BuildContext context, int index) {
# return some widget
}
),
In my case, I was using
singleChildScrollView
Column
Container
FutureBuilder
- Listview
and I wanted to scroll last scroll view with the whole column
for this add
physics: NeverScrollableScrollPhysics(),
this line in your listview.
Try using Slivers:
Container(
child: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate(
[
HeaderWidget("Header 1"),
HeaderWidget("Header 2"),
HeaderWidget("Header 3"),
HeaderWidget("Header 4"),
],
),
),
SliverList(
delegate: SliverChildListDelegate(
[
BodyWidget(Colors.blue),
BodyWidget(Colors.red),
BodyWidget(Colors.green),
BodyWidget(Colors.orange),
BodyWidget(Colors.blue),
BodyWidget(Colors.red),
],
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
delegate: SliverChildListDelegate(
[
BodyWidget(Colors.blue),
BodyWidget(Colors.green),
BodyWidget(Colors.yellow),
BodyWidget(Colors.orange),
BodyWidget(Colors.blue),
BodyWidget(Colors.red),
],
),
),
],
),
),
)
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("Login / Signup"),
),
body: new Container(
child: new Center(
child: ListView(
//mainAxisAlignment: MainAxisAlignment.center,
scrollDirection: Axis.vertical,
children: <Widget>[
new TextField(
decoration: new InputDecoration(
hintText: "E M A I L A D D R E S S"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(obscureText: true,
decoration: new InputDecoration(
hintText: "P A S S W O R D"
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(decoration: new InputDecoration(
hintText: "U S E R N A M E"
),),
new RaisedButton(onPressed: null,
child: new Text("SIGNUP"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new RaisedButton(onPressed: null,
child: new Text("LOGIN"),),
new Padding(padding: new EdgeInsets.all(15.00)),
new ListView(scrollDirection: Axis.horizontal,
children: <Widget>[
new RaisedButton(onPressed: null,
child: new Text("Facebook"),),
new Padding(padding: new EdgeInsets.all(5.00)),
new RaisedButton(onPressed: null,
child: new Text("Google"),)
],)
],
),
),
margin: new EdgeInsets.all(15.00),
),
),
);
Also, you can try use CustomScrollView
CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final OrderModel order = _orders[index];
return Container(
margin: const EdgeInsets.symmetric(
vertical: 8,
),
child: _buildOrderCard(order, size, context),
);
},
childCount: _orders.length,
),
),
SliverToBoxAdapter(
child: _buildPreloader(context),
),
],
);
Tip: _buildPreloader return CircularProgressIndicator or Text
In my case i want to show under ListView some widgets. Use Column does't work me, because widgets around ListView inside Column showing always "up" on the screen, like "position absolute"
Sorry for my bad english