I am using an API to build a movies application, I had a problem with making theListView to be from left to right instead of up and dowm.I am trying to create a horizontal list view but it displayed not as expected. You can see how it looks in the Image bellow. It works with me usually but it my first time to do that inside a listview builder. How to fix that?
Note: I want the full screen to be vertical and this part only horizontal.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child:
FutureBuilder(
future: getData(),
builder: (BuildContext context,AsyncSnapshot snapshot){
if(snapshot.data == null){
return Container(
child: Center(
child:CircularProgressIndicator() ,),);
}
else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context,int i){
if(snapshot.data==null){
return Center(
child: CircularProgressIndicator(),
);
}
else{
return Container(
height: 250,
child: Card(
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Image(image: NetworkImage(snapshot.data[i].poster))
],
),
),
);
}}
);
}
}
,),
),
);
}
}
Image
You can use scrollDirection: Axis.horizontal,
inside the Listview.Builder to make it scroll horizontally and add a width for the container that's being returned.
Try below code hope its helpful to you . declare your ListView.builder() like below refer Listview here
Container(
width: double.infinity,
height: 180,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 10,
itemBuilder: (BuildContext context, int i) {
return Container(
height: 50,
child: Card(
child: Image.network(
'https://tech.pelmorex.com/wp-content/uploads/2020/10/flutter.png',
),
),
);
},
),
),
Your result screen->
Related
I'm creating a chat feature in flutter but noticed this behavior on IOS that doesnt shrink the list so you can see the last sent message. How can I have the listview builder shrink to show the last message when the keyboard appears?
Note: This issue doesn't happen on Android
Scaffold(
resizeToAvoidBottomInset: true,
body: Stack(
children: <Widget>[
StreamBuilder(
stream: _chats,
builder: (context, snapshot) {
if (!snapshot.hasData) return Container();
return snapshot.hasData
? GestureDetector(
onPanDown: (_) {
FocusScope.of(context).requestFocus(FocusNode());
},
child: ListView.builder(
shrinkWrap: true,
controller: _scrollController,
padding: EdgeInsets.only(top: 10, bottom: 100),
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return MessageWidget(
tripId: widget.docId,
uid: snapshot.data.docs[index].data()["uid"],
messageId: snapshot.data.docs[index].id,
message: snapshot.data.docs[index].data()["message"],
sender: snapshot.data.docs[index].data()["senderName"],
sentByMe: widget.uid ==
snapshot.data.docs[index].data()["uid"],
mediaFileUrl:
snapshot.data.docs[index].data()["mediaFileUrl"],
);
}),
)
: Container();
},
);
]
)
)
I think you can try the 'reverse' property from the ListView.builder.
Tell me if this example didn't fit your needs, can you share us your code ? (I didn't see why you use a Stack and what could be the issue around that).
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: Stack(
children: <Widget>[
StreamBuilder<dynamic>(
builder: (context, dynamic snapshot) {
return GestureDetector(
onPanDown: (_) {
FocusScope.of(context).unfocus();
},
child: ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount: 100,
padding: const EdgeInsets.only(top: 10, bottom: 10),
itemBuilder: (context, index) {
return ListTile(title: Text(index.toString()));
},
),
);
},
),
],
),
),
Container(
padding: const EdgeInsets.all(8),
color: Colors.black12,
child: const TextField(),
),
],
),
);
}
}
I am trying to build a Nested listview but getting "RenderFlex children have non-zero flex but incoming height constraints are unbounded" error with below code.
Layers are like this...
Each item of a horizontal ListView has a Text widget and a ListView widget.
At the second level, each item of vertical ListView contains again a Text widget and a ListView.
At the third level, each item of the ListView contains a Text widget.
-Horizontal ListView
- Person's Name
- ListView
- Relation Name
- ListView
- Person's Name
Thanks in advance.
person.relations is a Map<String, List<Person>>
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Relationship Explorer"),
),
body: SafeArea(
child: BlocBuilder<RelationCubit, CubitState>(
bloc: _cubit,
builder: (_, state) {
if (state is RelationSuccessState) {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (_, outerIndex) =>
_relationTreeView(context, outerIndex),
itemCount: _cubit.people.length,
);
} else {
return WaitWidget();
}
},
),
),
);
}
Widget _relationTreeView(BuildContext context, int outerIndex) {
var person = _cubit.people[outerIndex];
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(person.displayName ?? ''),
Expanded(
child: Container(
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: person.relations?.length,
itemBuilder: (_, index) {
var persons = person.relations?[index];
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(person.relations!.keys.elementAt(index)),
Expanded(
child: Container(
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: persons.length,
itemBuilder: (_, index) {
var innerPerson = persons[index];
return Text(innerPerson.displayName ?? '');
},
),
),
)
],
);
},
),
),
),
],
);
}
Wrap the list view with a container and give a height.
I have several containiers inside a ListView which will result in a scrollable content within a page. Each container has a Column as child and within the Column I have a title and a divider, then the actual content.
I want one of the container to be something like:
Title
--------- (divider)
Scrollable content (most likely a ListView)
What I have so far:
Container(
height: 250,
child: Column(children: <Widget>[
Text('Title'),
Divider(),
SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context, int index) {
return Text('abc');
}
)
)
]
)
The thing is that I want the container to have a specific height, but I get an overflow pixel error.
Wrap your ListView with Expanded. Remove your SingleChildScrollView as ListView has its own scrolling behaviour. Try as follows:
Container(
height: 250,
child: Column(children: <Widget>[
Text('Title'),
Divider(),
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context, int index) {
return Text('abc');
}
),
)
]
))
Wrap your ListView.builder() widget inside a SizedBox() widget and specify available height after accommodating Title() widget.
Container(
height: 250,
child: Column(children: <Widget>[
Text('Title'),
Divider(),
SizedBox(
height: 200, // (250 - 50) where 50 units for other widgets
child: SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
itemCount: 15,
itemBuilder: (BuildContext context, int index) {
return Text('abc');
}
)
)
)
]
)
You can also use Container() widget instead SizedBox() widget but only if needed.
SizedBox() is a const constructor where Container() widget is not, so SizedBox() allows the compiler to create more efficient code.
I wanted to to make my home page scrollable i mean i want to scroll everthing on the body so i made a list view and inside the list view there are other widgets and under those widgets i want to show a future builder that has another listview.builder in it but i dont want it to be scrolled alone i want it to be scrolled with the other widgets in the home screen
this is my home screen body:
body: SafeArea(
child: ListView(
children: <Widget>[
Search(),
FeaturedProducts(),
OnSaleProducts(),
],
),
),
OnSaleProducts() is the widget that has a futurebuilder in it this is the code
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
child: FutureBuilder(
future: getOnSaleProduct(),
builder: (_, snapshot){
if (snapshot.connectionState == ConnectionState.waiting) {
return ListView.builder(
itemCount: 4,
itemBuilder: (_, index) {
return Column(
);
});
}else return ListView.builder(
scrollDirection: Axis.vertical,
itemCount: 9,
itemBuilder: (_, index) {
return InkWell(child: ProductCard(name: "new", price: 123, picture: '', onSale: true));
});
}));
}
Then you should not use a ListView inside OnSalesProduct() but a simple Column!
Column(children: List.generate(count, (int index) => widget(index))
Hopefully, what you are trying to know:
Scroll everthing on the body
Inside the scrollable view, want to show a future builder that has
another listview.builder
Don't want it to be scrolled alone it to be scrolled with the other
widgets in the home screen
Let's try this code, hopefully you will get your answerers and solution together:
SingleChildScrollView(
child: Column(
children: <Widget>[
Search(),
FeaturedProducts(),
OnSaleProducts(),
],
),
),
Now do this for OnSaleProducts() widget:
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height, // better for fixed size
width: double.infinity,
child: FutureBuilder<PopularFoodList>(
future: getOnSaleProduct(),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
scrollDirection: Axis.vertical,
itemCount: 9,
itemBuilder: (context, index) {
var item = snapshot.data[index]; // snapshot.data.anotherProperty[index]; // If your model has anotherProperty
return InkWell(child: ProductCard(name: item.name, price: item.price, picture: '', onSale: true));
});
} else if (snapshot.hasError) {
return Center(child: Text(snapshot.error.toString()));
}
return Center(child: CircularProgressIndicator());
})
);
}
I have widget which return CircularProgressIndicator()
it shows on the circular mark upper left of screen.
However I want to put this as overlay and put at the center of screen.
I am checking widget list but I cant find what Widget should I use as overlay.
On which layer should I put this on??
For now my code is like this ,when loading it shows CircularProgressIndicator instead of ListView
However I want to put CircularProgressIndicator() on ListView
Widget build(BuildContext context) {
if(loading) {
return CircularProgressIndicator();
}
return ListView.builder(
controller: _controller,
itemCount: articles.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(articles[index]),
);
},
);
}
Thank you very much for answers.
I solve with stack Widget like this below.
At first I try to use overlay, but I bumped into some errors.
So, I use simply stack.
#override
Widget build(BuildContext context) {
Widget tempWidget = new CircularProgressIndicator();
if(loading) {
tempWidget = new CircularProgressIndicator();
}
else {
tempWidget = new Center();//EmptyWidget
}
return Stack(
children: <Widget>[
ListView.builder(
controller: _controller,
itemCount: articles.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(articles[index].title),
onTap: () => onTapped(context,articles[index].url),
);
},
),
Center(
child: tempWidget
),
]
);
}
Stack(
children: <Widget>[
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
color: Colors.red,
);
},
itemCount: 10,
),
Center(
child: CircularProgressIndicator(),
),
],
)
Stack(
children: <Widget>[
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
color: Colors.red,
);
},
itemCount: 10,
),
isLoading? Container(child: Center(
child: CircularProgressIndicator(),
)): Container(), //if isLoading flag is true it'll display the progress indicator
],
)
or you can use futureBuilder or streamBuilder when loading data from somewhere and you want to change the ui depending on the state
To overlay or position items on top of each other you would usually use a Stack widget or Overlay as described here. For your usecase I would recommend checking out the modal progress hud package.