Flutter 2 Streambuilders in Column - flutter

I have 2 streambuilders that I want to display, both with a Listview builder inside them. I want to put both those streambuilders in a scrollabe column but it just won't work. I tried wrapping them in an Expanded or Flexible and I just can't figure it out. The problem when using the expanded widget is that even if the widget doesn't have any children, it still takes in a big part of the screen. When for example streambuilder 1 doesn't have data, it still uses a proportion of the screen.
Thanks in advance!
This is my code briefly:
SingleChildScrollView(
child: Column(
children: [
Expanded(
child: StreamBuilder(
stream: stream1,
builder: (context, snapshot) {
return ListView.builder();
},
),
),
Expanded(
child: StreamBuilder(
stream: stream2,
builder: (context, snapshot) {
return ListView.builder();
},
),
),
],
),
),

SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: StreamBuilder(
stream: stream1,
builder: (context, snapshot) {
return ListView(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: firstList(),
),
},
),
),
Expanded(
child: StreamBuilder(
stream: stream2,
builder: (context, snapshot) {
return ListView(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
children: secondList(),
),
},
),
),
],
),
)
You can make the ListView widget never scrollable by setting physics property to physics: NeverScrollableScrollPhysics(),
and
With shrinkWrap: true, you can change this behavior so that the ListView only occupies the space it needs (it will still scroll when there more items).
its make two diferent StreamBuilder widget in a single scrollable.

Related

RenderFlex children have non-zero flex but incoming height constraints are unbounded: Nested ListView

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.

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

Join two ListViews

I want to create a ToDo-App that saves the ToDo's in Firestore.
I am already able to add every new ToDo Item to Firestore and now I want those Items that were added to pop up when the application opens.
I have made the following:
body: Column(
children:<Widget>[
StreamBuilder<QuerySnapshot>(
stream:FirebaseFirestore.instance.collection("TO-DO-Collection").snapshots(),
builder: (context,snapshot){
if(!snapshot.hasData) return LinearProgressIndicator();
return Expanded(
child: _buildList(snapshot.requireData),
);
},
),
Expanded(
child:ListView(
children: _getItems(),
),
),
],
),
Here the method to build the List with all the stored ToDo's:
Widget _buildList(QuerySnapshot snapshot){
return ListView.builder(
itemCount: snapshot.docs.length,
itemBuilder: (context,index){
final doc=snapshot.docs[index];
return _buildTodoItem(doc["task"]);
},
);
}
(The function _buildTodoItem simply returns a List Tile)
This creates two ListViews (one of the first half of the screen and the other one on the other). Is there any possible way to unify both?
Wrap your column with SingleChildScrollView and put physics: NeverScrollableScrollPhysics(). This will merge the scroll of both of your lists.
body: SingleChildScrollView(
child :Column(
children:<Widget>[
StreamBuilder<QuerySnapshot>(
stream:FirebaseFirestore.instance.collection("TO-DO-Collection").snapshots(),
builder: (context,snapshot){
if(!snapshot.hasData) return LinearProgressIndicator();
return _buildList(snapshot.requireData);
},
),
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
children: _getItems(),
),
],
),),
Widget _buildList(QuerySnapshot snapshot) {
return ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.docs.length,
itemBuilder: (context, index) {
final doc = snapshot.docs[index];
return _buildTodoItem(doc["task"]);
},
);
}

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.

Having a different StreamBuilder for every tab in TabBarView

I am trying to create a home page that has 3 tabs: Friends, Groups and Events.
After finally managing to load events for the current user only, I realised ill have a hard time loading different data for each tab - as the StreamBuilder stream: will always be the same for all the tabs.
I need help finding a way to have a different StreamBuilder for each of my tabs.
Code below:
StreamBuilder(
stream: _streamer(),//Firestore.instance.collection("Events").snapshots(),
builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
if (!snapshot.hasData) return const Text("Loading...");
return new SizedBox(
height: MediaQuery.of(context).size.height - 42 - MediaQuery.of(context).padding.bottom -AppBar().preferredSize.height - kToolbarHeight,
child: Column(
children: <Widget>[
Expanded(
child: TabBarView(
controller: _tabController,
children: <Widget>[
Container(
child: ListView.separated(
itemCount: snapshot.data.length,
itemBuilder: (context, index) =>
_buildListItem(context,
snapshot.data[index]),
separatorBuilder: (context, index) {
return Divider();
},
shrinkWrap: true,
),
),
Container(
child: ListView.separated(
itemCount: snapshot.data.length,
itemBuilder: (context, index) =>
_buildListItem(context,
snapshot.data[index]),
separatorBuilder: (context, index) {
return Divider();
},
shrinkWrap: true,
),
),
Container(
child: ListView.separated(
itemCount: snapshot.data.length,
itemBuilder: (context, index) =>
_buildListItem(context,
snapshot.data[index]),
separatorBuilder: (context, index) {
return Divider();
},
shrinkWrap: true,
),
),
],
),
)
],
));
},
)
This is how the home page looks
I assume you're loading all data required for all your tabs using that stream. What you could do is have distinct pairs of stream/StreamBuilder for each tab:
... // widgets leading up to the TabBarView
TabBarView(
controller: _controller,
children: <Widget>[
StreamBuilder(
stream: friendsStream,
builder: (BuildContext context, AsyncSnapshot<SomeData> snapshot) {
return FriendsWidget();
}
),
StreamBuilder(
stream: groupsStream,
builder: (BuildContext context, AsyncSnapshot<SomeData> snapshot) {
return GroupsWidget();
}
),
//... etc
]
)
You could also wrap ONLY the widgets that should be rebuilt with a StreamBuilder instead of wrapping the whole parent widget:
... // widgets leading up to the TabBarView
TabBarView(
controller: _controller,
children: <Widget>[
Column(
children: <Widget>[
SomeWidget(),
AnotherWidget(),
StreamBuilder(
stream: friendsStream,
builder: (BuildContext context, AsyncSnapshot<SomeData> snapshot) {
return FriendsWidget();
}
)
]
),
// ... etc
]
)
If you are compelled to load all your data from the database at once, you could use a Repository class to load and store all your data, and then, depending on your architecture, have streams built from that class.
As a side note, I highly recommend using a Bloc with BlocBuilder. Blocs are just far superior to other designs (in most cases). flutter_bloc is my favorite.