Flutter - How to make PageView & ListView? - dart

I'm trying to make a Carousel using PageView, PageController and ListView from this Horizontally scrollable cards with Snap effect in flutter. But it throwed this exception...
══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (17678): The following assertion was thrown during performResize():
I/flutter (17678): Horizontal viewport was given unbounded height.
I/flutter (17678): Viewports expand in the cross axis to fill their container and constrain their children to match
I/flutter (17678): their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
I/flutter (17678): vertical space in which to expand.
Can someone help me to fix it?
I want to add this Carousel inside of Stack-filled with background image, transform class, and fade transition.
#override
void initState() {
super.initState();
controller = PageController(
initialPage: 0,
keepPage: true,
);
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
builder: (BuildContext context, Widget child) {
return Scaffold(
//BODY
body: ListView(children: <Widget>[
new Stack(
children: <Widget>[
new AspectRatio(...),
new Transform(...),
//THIS IS
new ListView.builder(
itemCount: 3,
scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric(vertical: 16.0),
itemBuilder: (BuildContext context, int index) {
if (index % 3 == 0) {
return _buildCarousel(context, index ~/ 3);
} else {
return Divider();
}
},
),
}
}
}
Widget _buildCarousel(BuildContext context, int carouselIndex) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Carousel $carouselIndex'),
SizedBox(
// you may want to use an aspect ratio here for tablet support
height: 200.0,
child: PageView.builder(
// store this controller in a State to save the carousel scroll position
controller: PageController(viewportFraction: 0.8),
itemBuilder: (BuildContext context, int itemIndex) {
return _buildCarouselItem(context, carouselIndex, itemIndex);
},
),
)
],
);
Widget _buildCarouselItem(
BuildContext context, int carouselIndex, int itemIndex) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 4.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
),
);
This is the full code https://pastebin.com/xXRkaWuR

As you might have guessed from the error, basically it means since you haven't specified a finite height,ListView is getting infinite height.
Try using shrinkWrap: true inside your ListView.builder and ListView.
Or alternatively you can also try wrapping your ListViews in a Container or SizedBox of finite height.
Example-
Container(
height: 200.0,
child: ListView(
/*Remaining Code*/
),
)
You can try doing the same with ListView.builder

Related

Widget inside a column not scrolling completely when scrolling Scroll-able widget

I have a NestedScrollView whose body contains a TabBarView. And one of the tabs has a column with an image and a scrollable widget(GridView.builder). When scrolling this scrollable widget, the images get stuck halfway(as if it was pinned in that position).
Here's the code
//home.dart
class _HomePage extends State<HomePage> {
#override
Widget build(BuildContext context) {
return Container( //this is the image that gets stuck
child: Column(
children: <Widget>[
new Container(
child: new Image.asset(
"images/product.jpg",
fit: BoxFit.fitWidth,
),
),
Expanded(
child: FreshFinds(), //this is the scrollable widget
),
],
),
);
}
}
// Freshfind.dart
#override
Widget build(BuildContext context) {
return Card(
child: GridView.builder(
// shrinkWrap: true,
itemCount: 50,
physics: ScrollPhysics(),
gridDelegate:
new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index) {
return FutureBuilder(
future: fetchdata(index),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData)
return buildfake(index);
else
return buildcard(snapshot.data, index);
},
);
},
),
);
}
Here is a video of the problem
I think you need to use SliverAppBar() widget alongside with TabBar().
Here's a resource that might help you

How to vertical align ListView in the middle

I want my list item in the middle of the ListView
#override Widget build(BuildContext context)
{
List<String> listName = ['Woody', 'Buzz', 'Rex'];
return Container
(
decoration: BoxDecoration(border: Border.all(color: Colors.pinkAccent)),
width: 400,
height: 700,
alignment: Alignment.centerLeft,
child: ListView.builder
(
itemCount: listName.length,
itemBuilder: (context, index)
{
return OurName(listName[index]);
},
),
);
}
This is when I use shrinkWrap, when I scroll up it's cut off and it can't be scroll down
shrinkWrap
This is what I expected expected
The key to your issue is the shrinkWrap property of ListView. So to fix this you can do something like this:
Container(
alignment: Alignment.centerLeft,
child: ListView.builder(
itemBuilder: (context, index) {
return Text("The index$index");
},
shrinkWrap: true,
itemCount: 30,
),
),
For me works this code!
#override
Widget build(BuildContext context) {
return Container(
height: double.infinity,
width: double.infinity,
alignment: Alignment.center,
child: ListView.builder(
shrinkWrap: true,
itemCount:rows.length,
itemBuilder: (
context,
index,
) {
return ...;
}),
);
}
I came here to center vertically (and horizontally) my listView, and came up with this:
#override
Widget build(BuildContext context) {
List<String> listName = ['Woody', 'Buzz', 'Rex'];
return Align(
child: ListView.builder(
itemCount: listName.length,
itemBuilder: (context, index) {
return Center(child: Text(listName[index]));
},
shrinkWrap: true,
),
);
}
i dont get what you mean do you want to align the whole listview then use a center widget and align the listview in the center, or use Align widget and manually align it by
Align(
alignment: Alignment.centerRight,
child: //here your list,
)
if thats not what you want or doesn't get the job done then please explain more.

Flutter Stepper horizontal type not working

I have a problem with changing the Stepper type from vertical to horizontal.
This is my code:
body: new ListView.builder(
itemCount: data == null ? 0 : 5,
itemBuilder: (BuildContext context, int index) {
return new Card(
//child: new Text(data[index]["title"]),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Stepper(
steps: my_steps,
type: StepperType.horizontal,
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue, VoidCallback onStepCancel}) {
return Row(
children: <Widget>[
Container(
child: null,
),
Container(
child: null,
),
],
);
},
//type: StepperType.horizontal,
),
));
},
),
After I uncomment the type I get this error:
I/flutter (10148): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY
╞═════════════════════════════════════════════════════════ I/flutter
(10148): The following assertion was thrown during performLayout():
I/flutter (10148): RenderFlex children have non-zero flex but incoming
height constraints are unbounded. I/flutter (10148): When a column is
in a parent that does not provide a finite height constraint, for
example if it is I/flutter (10148): in a vertical scrollable, it will
try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (10148): flex on a child (e.g. using Expanded) indicates
that the child is to expand to fill the remaining I/flutter (10148):
space in the vertical direction.
Your ListView has unbounded heigh so it doesn't know how much space to use for each child, which is a Stepper.
Give it some constraints, such minimum height size for each and you should be fine.
(...)
ConstrainedBox(
constraints: BoxConstraints.tightFor(height: 200.0),
child: Stepper(
steps: my_steps(),
type: StepperType.horizontal,
(...)
You can use the SizedBox() or Container() widget and set it height
SizedBox(
height: 200,
child: Card(
//child: new Text(data[index]["title"]),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Stepper(
steps: my_steps(),
type: StepperType.horizontal,
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue, VoidCallback onStepCancel}) {
return Row(
children: <Widget>[
Container(
child: null,
),
Container(
child: null,
),
],
);
},
//type: StepperType.horizontal,
),
)),
)

Strange Bug with horizontal ListView inside Vertical SliverList

After scrolling vertically upwards, the horizontal ListView scrolls itself to the right.
The error only occurs when, at the time the horizontal Listview is displayed, the finger no longer touches the touchscreen and the vertical SliverList continues to run by itself.
Here is the code to reproduce the error:
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index == 0)
return SizedBox(
height: 50,
child: ListView.builder(
itemBuilder: (context, index) => Container(
width: 200,
color: Colors.black45,
margin: const EdgeInsets.symmetric(horizontal: 8),
),
scrollDirection: Axis.horizontal,
),
);
return Container(
height: 200,
margin: const EdgeInsets.symmetric(vertical: 8),
color: Colors.black45,
);
},
),
)
],
);
}
You should add the key to your ListView.
In here, we can use key: PageStorageKey()

Flutter scrollable body with horizontal list and grid as children

I'm having a hard time understanding how to best create a scrollable container for the body that holds inside children that by default are scrollable as well.
In this case the grid shouldn't scroll but it's the entire page that should scroll so you are able to see more of the elements inside the grid. So basically the whole content should move vertically with the addition of the ListView moving horizontally (but that works fine already)
I had it working but it was using a bunch of "silver" widget, and I'm hoping there's a better solution that works without using all those extra widgets.
Thanks
Here's my code so far:
class GenresAndMoodsPage extends AbstractPage {
#override
String getTitle() => 'Genres & Moods';
#override
int getPageBottomBarIndex() => BottomBarItems.Browse.index;
static const kListHeight = 150.0;
Widget _buildHorizontalList() => SizedBox(
height: kListHeight,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 20,
itemBuilder: (_, index) =>
CTile(heading: 'Hip Hop', subheading: '623 Beats'),
),
);
Widget _buildGrid() => GridView.count(
crossAxisCount: 2,
crossAxisSpacing: LayoutSpacing.sm,
mainAxisSpacing: LayoutSpacing.sm,
children: List.generate(10, (index) {
return CTile(
padding: false,
heading: 'Kevin Gates Type Beat',
subheading: '623 FOLLOWERS',
width: double.infinity,
);
}),
);
#override
Widget buildBody(_) {
return ListView(children: [
CSectionHeading('Popular Genres & Moods'),
_buildHorizontalList(),
CSectionHeading('All Genres & Moods'),
_buildGrid(),
]);
}
}
The result should be something like this
Create List with Horizontal Scroll direction and called it as a child for Vertical Scroll direction.
body: new ListView.builder(itemBuilder: (context, index){
return new HorizList();
})
class HorizList extends StatelessWidget{
#override
Widget build(BuildContext context) {
return new Container(
height: 100.0,
child: new ListView.builder(itemBuilder: (context, index){
return new Card(child: new Container(width: 80.0,
child: new Text('Hello'),alignment: Alignment.center,));
}, scrollDirection: Axis.horizontal,),
);
}
}
As we want Popular Genres & Moods section also to scroll, we should not using nestedScroll. In above example GridView is nested inside `ListView. Because of which when we scroll, only the GridView will scroll.
I used Only one ListView to achieve the similar screen.
Number of children = (AllGenresAndMoodsCount/2) + 1
divide by 2 as we are having 2 elements per row
+1 for the first element which is horizontal scroll view.
Please refer the code:
import 'package:flutter/material.dart';
void main() {
runApp(new Home());
}
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
var image = new Image.network("http://www.gstatic.com/webp/gallery/1.jpg");
var container = new Container(
child: image,
padding: EdgeInsets.only(left: 5.0, right: 5.0, top: 5.0, bottom: 5.0),
width: 200.0,
height: 200.0,
);
return MaterialApp(
title: "Scroller",
home: Scaffold(
body: Center(
child: new ListView.builder(
itemBuilder: (context, index) {
if (index == 0) { //first row is horizontal scroll
var singleChildScrollView = SingleChildScrollView(
child: Row(
children: <Widget>[
container,
container,
container,
],
),
scrollDirection: Axis.horizontal);
return singleChildScrollView;
} else {
return new Row(
children: <Widget>[container, container],
);
}
},
itemCount: 10, // 9 rows of AllGenresAndMoods + 1 row of PopularGenresAndMoods
)),
),
);
}
}

Resources