ListView.builder inside futurebuilder inside Listview - flutter

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());
})
);
}

Related

Firebase String doesn't automatically line break when inserting it in Flutter Text Widget

So I use Firebase as my backend.
The String about which Im talking looks like this:
When I add this String as a variable in my Text Widget
Text("${beschreibung}")
the text doesn't automatically line break, its just cut off by the right side of the screen
How can I achieve a behaviour where this doesn't happen & get flutter to detect the spaces to automatically line break?
Additional Details
Here Im getting the data from firebase and passing it on:
class Produkte extends StatelessWidget {
final Stream<QuerySnapshot> data =
FirebaseFirestore.instance.collection("products").snapshots();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
width: MediaQuery.of(context).size.width,
child: StreamBuilder<QuerySnapshot>(
stream: data,
builder: ((BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Some error");
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("loading");
}
final data = snapshot.requireData;
return Container(
height: 800,
child: GridView.builder(
itemCount: data.size,
itemBuilder: (context, index) {
return ProductTile(
titel: data.docs[index]["Name"].isNotEmpty
? data.docs[index]["Name"]
: " ",
beschreibung:
data.docs[index]["Beschreibung"].isNotEmpty
? data.docs[index]["Beschreibung"]
: " ");
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 5,
crossAxisSpacing: 2),
));
}),
),
),
),
);
}
}
& here Im using the data
class Produkt extends StatelessWidget {
Produkt({required this.titel, required this.beschreibung});
final List<String> beschreibung;
final String titel;
#override
Widget build(BuildContext context) {
return Scaffold(body:
Container(
height: 350,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: beschreibung.length,
itemBuilder: (context, index) {
return Text("${beschreibung[index]}");
},
),
),
);
}
}
Add width to the container so the text knows where to break and use a new line and remove the axis horizontal..
return Scaffold(body:
Container(
height: 350,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
itemCount: beschreibung.length,
itemBuilder: (context, index) {
return Text("${beschreibung[index]}");
},
),
),
If you wish to keep the horizontal scroll but still have the text in one screen then add a container to the text
return Scaffold(body:
Container(
height: 350,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: beschreibung.length,
itemBuilder: (context, index) {
return Container( width: MediaQuery.of(context).size.width,
child : Text("${beschreibung[index]}")
);
},
),
),

How to create horizontal Listview in listview builder flutter

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->

StreamBuilder inside the ListviewBuilder not scrolling

Problem: I am beginner for flutter developing. I tried to get data from firestore and display it. But scrolling listview didn't respond to one finger so I had to use more than one. How to solve this problem.
body: StreamBuilder(
stream: _firebase_auth.collection("ContactData").snapshots(),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemExtent: 100.0,
itemBuilder: (context, index) {
DocumentSnapshot data = snapshot.data.docs[index];
return Card(
child: ListView(padding: EdgeInsets.all(8.0), children: [
Text('sds'),
Text('sds'),
Text('sds'),
Text('sds'),
Text('sds'),
]),
);
});
} else {
return Text('Loading Data.....');
}
},
),
you should wrap streamBuilder with the SingleChild scroll view or use shrinkWrap: true,physics: ScrollPhysics(),
body: StreamBuilder(
stream: _firebase_auth.collection("ContactData").snapshots(),
builder: (BuildContext context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: snapshot.data.docs.length,
itemExtent: 100.0,
itemBuilder: (context, index) {
DocumentSnapshot data = snapshot.data.docs[index];
return Card(
child: ListView(padding: EdgeInsets.all(8.0), children: [
Text('sds'),
Text('sds'),
Text('sds'),
Text('sds'),
Text('sds'),
]),
);
});
} else {
return Text('Loading Data.....');
}
},
),
add this line in listView.builder
physics: AlwaysScrollableScrollPhysics(),
Wrap stream builder with SingleChildScrolView.
This will make the screen a scrollable element.
Set physics of ListView.builder to NeverScrollablePhysics.
This will prevent the scrolling of the parent ListView.Builder, but it's okay because it's parent, SingleChildScrollView is
scrollable.
Set physics of ListView to Scrollable
If you want to, not sure if you want to scroll these items or just display.

Flutter - Evenly spaced padding at the bottom of each ListView item

I am trying to add 70.0px at the bottom of each of my Container item in my ListView.
I have been looking at a lot of answers from StackOverflow and trying them in many different ways, and adding padding inside ListView doesn't work somehow. However, I still couldn't tackle it.
Can someone please give me some advice please?
class PortfolioRow extends StatelessWidget {
#override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return Container(
margin: const EdgeInsets.only(bottom: 70.0),
child: StreamBuilder(
stream: Firestore.instance
.collection('portfolio')
.where('category')
.snapshots(),
builder: (context, snapshot) {
return ListView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
itemExtent: 450.0,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) => portfolioContainer(
context, snapshot.data.documents[index]));
}));
...
}
Widget portfolioContainer(
BuildContext context, DocumentSnapshot documentSnapshot) {
return Align(
child: SizedBox(
height: 540,
width: 330,
child: Container( // if I add padding bottom here, there will be a pixel overflow in my container
child: Column(children: [
Container(
...
}
ListView has a named constructor for exactly that : ListView.separated(). The separatorBuilder parameter lets you specify a widget that will be added at the bottom of each item :
ListView.separated(
itemCount: 25,
separatorBuilder: (BuildContext context, int index) => Divider(),
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text('item $index'),
);
},
)

How to display progress indicator in flutter when a certain condition is true?

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.