Flutter - unboundedHeight error within ListView - flutter

Flutter newbie here!
Currently, my Scaffold has 2 listview builders and the bottom one is giving me the unbounded height (!constraints.hasBoundedHeight error) issue.
I have tried using shrinkWrap on all 3 list views, as suggested in similar questions but I get the same error.
The only thing that works is wrapping the FutureBuilder in a SizedBox. But that seems unintuitive to me, as I would want it to ideally expand as needed and be scrollable.
My rough solution is to maybe dynamically calculate the height based on the number of items the FutureBuilder needs, but again, I feel there should be a better solution.
My code snippet is attached below:
return Scaffold(
appBar: AppBar(),
body: ListView(
children: [
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 2,
itemBuilder: (context, index) {
return const SuggestCard(
indexKey: 'takt',
);
}),
FutureBuilder<AnimeDetails>(
future: _animeDetail,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: 2, //Number of anime from list
itemBuilder: (context, index) {
var anime = snapshot.data; //Get the data from the index
return AnimeCard(
anime: anime,
);
});
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
],
),
);

As per your comment I think below link will helpful to you.
Lists

The parent ListView handling scroll event for body and while second ListView will have fixed height, you can do it like this
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => ListView(
children: [
SizedBox(
height: constraints.maxHeight * .3,
child: ListView.builder(
itemCount: 122,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => Text("H $index"),
),
),
ListView.builder(
shrinkWrap: true,
physics:
const NeverScrollableScrollPhysics(), // parent controll the scroll event
itemCount: 44,
itemBuilder: (context, index) => Text("$index"),
),
],
),
));

I just added the below lines to your code. You can try the below code.
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
return Scaffold(
appBar: AppBar(),
body: ListView(
children: [
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 2,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return const SuggestCard(
indexKey: 'takt',
);
}),
FutureBuilder<AnimeDetails>(
future: _animeDetail,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: 2, //Number of anime from list
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
var anime = snapshot.data; //Get the data from the index
return AnimeCard(
anime: anime,
);
});
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
],
),
);

Related

Flutter : Showing long widget list using ListView.builder() and ListTile

I have a Widget list with millions of widgets and some of them are wider than screen.
I need to use ListView.builder() and ListTile to save time while running like this:
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
controller: scrollController,
itemCount: widgetList.length,
itemBuilder: (context, i) =>
ListTile(
title: widgetList[i]
)
);
But when I run it, those ListTile that their title is wider than screen will overflow on the right because ListView.builder() not wide enough.
If I assign a big width to ListView.builder() like this will works fine but will remain a lot of blank even if all widgets in list are short:
ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: [
Container(
width: 2000,
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
controller: scrollController,
itemCount: widgetList.length,
itemBuilder: (context, i) =>
ListTile(
title: widgetList[i]
)
))]);
Any idea to improve this function?
---------------update-----------
My widgetList contains Column/Row etc.
But let's start with only one Text().
Example:
ListView.builder(
restorationId: 'sampleItemListView',
itemCount: 1000000,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(
"abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz",
maxLines: 1,
),
);
},
)
The text is too long but I don't want it change line .
What can I do to read full text?
Use like below, do not specify the hight and width for the widgets
#override
Widget build(BuildContext context) {
var items = List<SampleItem>.generate(
1000,
(i) => const SampleItem(
'范植勝',
'Showing long widget list using ListView.builder() and ListTile',
Icons.favorite,
));
return Scaffold(
body: ListView.builder(
restorationId: 'sampleItemListView',
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
final item = items[index];
return ListTile(
title: Text(item.name),
subtitle: Text(item.decsription),
leading: Icon(item.icons),
onTap: () {
Navigator.restorablePushNamed(
context,
SampleItemDetailsView.routeName,
);
});
},
),
);
}

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.

ScrollController not working without a container

I have a ScrollController in my page to work with infinite scroll but when the list builder is not in a Container the ScrollController listeners does not work.
Works
Container(
height: 400,
child: Observer(
builder: (_) {
return ListView.builder(
shrinkWrap: true,
controller: _scrollController,
itemCount: passeiosController.passeios.length,
itemBuilder: (_, index) => PasseioCard(
passeioModel: passeiosController.passeios[index],
),
);
},
),
)
Not working
Observer(
builder: (_) {
return ListView.builder(
shrinkWrap: true,
controller: _scrollController,
itemCount: passeiosController.passeios.length,
itemBuilder: (_, index) => PasseioCard(
passeioModel: passeiosController.passeios[index],
),
);
},
)
It worked. I had a list view builder inside a listview. Putting the controller in the parent listview worked correctly.

Fix Renderbox Error with Horizontal Listview

I am trying to change my ListView to be Shown horizontally instead of veritcally by default. However, when I have done this, I face the following an error. The error occurs at both the Widgets returned by the _buildListItem function and disappears when the scrolldirection is changed from vertical back to horizontal.
RenderBox was not laid out: RenderPointerListener#98473 relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
The code of the ListView Builder is
Widget _buildListItem (BuildContext context,DocumentSnapshot doc,int index)
{
if(index ==0)
{
return ListTile(title:Container( height:200,width: 100,child: Card(shape: new RoundedRectangleBorder(),child:Column(children:<Widget>[new Flexible(child:Text(widget.prayerName,style: TextStyle(fontSize: 32,fontWeight: FontWeight.bold))),Text(widget.blurb,style: TextStyle(fontSize: 28))]))));
}
else {
return RaisedButton(child: Text("a"),);
}
}
Here is the body of my build widget where my list view is declared
body: StreamBuilder(
stream: Firestore.instance.collection('quranKhwani').document(widget.docID).collection("juz").orderBy("juzNumber").snapshots(),
builder: (context,snapshot)
{
if(!snapshot.hasData)return const Text("Loading..");
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context,index)=>
_buildListItem(context,snapshot.data.documents[index],index),
itemCount: snapshot.data.documents.length,
);
}
)
));
Container(
height: _height //add height
child: StreamBuilder(
builder: (context, snapshot) {
return ListView.builder(
itemBuilder: (context, index) {},
scrollDirection: Axis.horizontal,
);
},
),
)
You have to give height to the StreamBuilder like:
body: Container(
height: 300, // Height you want
child:
StreamBuilder(
stream: Firestore.instance.collection('quranKhwani').document(widget.docID).collection("juz").orderBy("juzNumber").snapshots(),
builder: (context,snapshot)
{
if(!snapshot.hasData)return const Text("Loading..");
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (context,index)=>
_buildListItem(context,snapshot.data.documents[index],index),
itemCount: snapshot.data.documents.length,
);
}
),
),
),