How to build pageview in column in flutter - flutter

I want to create a ui in flutter like this
And I have managed it. As I have used pageview builder for this, it is asking for a page height, now the problem is that I have given the height according to this screen and now in mobiles with shorter screeen I am not able to get same results.
Container(
margin: EdgeInsets.fromLTRB(20.w, 20.h, 10.w, 3.h),
height: 520.h,
child: Column(
children: [
Expanded(
child: PageView.builder(
itemCount: controller.pages.length,
controller: controller.pageController,
itemBuilder: (context, index) {
return GridView.builder(
// physics: NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemCount: controller.pages[index].length,
itemBuilder: ((context, index1) {
return GestureDetector(
onTap: () async {
//some code
},
child: MenuTileWidget(
title: controller
.pages[index][index1].title,
image: controller
.pages[index][index1].image,
),
);
}));
}),
),
SmoothPageIndicator(
controller: controller.pageController,
count: controller.pages.length,
effect: WormEffect(
activeDotColor: color2,
spacing: 14.w,
dotWidth: 16.sp,
dotHeight: 16.sp,
dotColor: Colors.white),
),
],
),
),
And if I comment height, it gives exception.

Try using MediaQuery() like this:
...
Container(
margin: EdgeInsets.fromLTRB(20.w, 20.h, 10.w, 3.h),
height: MediaQuery.of(context).size.height,
child: Column(
...
This is probably going to hide your indicators. So to solve this use Stack() instead of Column() then control the position of the indicator. Here is the full code:
Container(
margin: EdgeInsets.fromLTRB(20.w, 20.h, 10.w, 3.h),
height: 520.h,
child: Stack(
children: [
Expanded(///<- Remove this you won't need it anymore
child: PageView.builder(
itemCount: controller.pages.length,
controller: controller.pageController,
itemBuilder: (context, index) {
return GridView.builder(
// physics: NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemCount: controller.pages[index].length,
itemBuilder: ((context, index1) {
return GestureDetector(
onTap: () async {
//some code
},
child: MenuTileWidget(
title: controller
.pages[index][index1].title,
image: controller
.pages[index][index1].image,
),
);
}));
}),
),
Align( ///<- Or Positioned
alignment: Alignment.bottomCenter,
child: SmoothPageIndicator(
controller:
controller.pageController,
count:
controller.pages.length,
effect: WormEffect(
activeDotColor: color2,
spacing: 14.w,
dotWidth: 16.sp,
dotHeight: 16.sp,
dotColor:
Colors.white),
),
)
],
),
),

Related

GridView infinite scrolling CircularProgressIndicator position

In my gridView there is a condition when to show CircularProgressIndicator(), but it is displayed incorrectly, in the gridView element, I need it to be displayed below the gridView. How can I show CircularProgressIndicator() correctly?
Widget buildCatalog(List<Product> product) => GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
// mainAxisExtent: ,
maxCrossAxisExtent: 300,
childAspectRatio: MediaQuery.of(context).size.width*1.22 /
(MediaQuery.of(context).size.height),
crossAxisSpacing: 10,
mainAxisSpacing: 10),
controller: sController,
itemCount: product.length + 1,
itemBuilder: (context, index) {
if (index < product.length) {
final media = product[index].media?.map((e) => e.toJson()).toList();
final photo = media?[0]['links']['local']['thumbnails']['350'];
final productItem = product[index];
return GestureDetector(
onTap: () {
},
child: Container(
child: Column(
children: <Widget>[
InkWell(
child: Container(
margin: EdgeInsets.only(top: 5),
child: Image.network(...)
),
),
),
SizedBox(
height: 10,
),
Text(
'${productItem.name}\n',
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
// Spacer(),
SizedBox(height: 8),
Text('${productItem.price} ₸',
textAlign: TextAlign.start,
style: TextStyle(fontSize: 20, color: Colors.red)),
SizedBox(height: 5),
buildButton(index, productItem.id),
],
),
),
);
}
return const Center(child: CircularProgressIndicator(),);
},
);
wrap Gridview() and CircularProgressIndicator() into a column,
and change shrinkWarp and physics like below
Column(
children: [
Gridview.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: product.length + 1,
itemBuilder: (context, index) {
//return something you want
},
),
const CircularProgressIndicator()
],
)

How to solve Flutter bottom overflow error

I have tried to create Listview.builder with help of API(for displaying API product). but i got error in bottom pixel. i tried many ways to solve this problem. but couldn't find anything,
how can i solve this problems by editing code... And what is the main reason for this error
code is here
Container(
height: 650,
child: FutureBuilder(
future: _getProduct(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return const Center(child: Text("Loading"));
} else {
return GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: snapshot.data?.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(right: 10),
child: Container(
width: 130,
height: 485,
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(10)),
child: Container(
height: 240,
child: Column(
children: [
Padding(
padding: EdgeInsets.all(5),
child: Image.network(
snapshot.data![index].image)),
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Expanded(
child: Text(
snapshot.data![index].name,
overflow: TextOverflow.fade,
maxLines: 2,
style: const TextStyle(
fontSize: 15,
fontWeight:
FontWeight.w700),
)),
Text(
snapshot.data![index].price)
],
),
)
],
),
),
),
);
},
);
}
}),
)
Issue with this
GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
Needed to add Shrinkwrap & Add the Ratio
shrinkwrap: true,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.8,
),
I am a beginner in flutter,
I changed to your code and working ok,
need a single line to be added to your code...
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1 / 1.5,//<- add this one (it will increase height of your card or container)
crossAxisCount: 2),

Flutter: FlexLayoutManager similar to the one in native android

So I'm trying to implement a flex listview similar to the google FlexLayoutManager to the horizontal axis with wrap, you can see an example in the wrap section
https://github.com/google/flexbox-layout/raw/main/assets/flex-wrap.gif
here is my code:
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
padding: EdgeInsetsDirectional.only(start: 16, end: 12),
itemBuilder: (context, index) {
return InkWell(
onTap: (){
},
child: Container(
height: 24,
alignment: Alignment.center,
child: Text(
categories[index].name,
),
),
);
},
)
what I have to add to my listview to make the items wrap and move to the next row if they exceeded the screen width?
Not tested, but as I indicated in my comment, I'd use something like:
Wrap(
children: [
for (final c in categories)
InkWell(child: Text(c.name)),
]);
adding of course all your parameters, and the extra container.
As an alternative, you can use a GridView.builder instead of ListView.builder:
Creates a scrollable, 2D array of widgets that are created on demand.
result:
I have made my window very small and the children still wrap:
With the window maximized:
code:
GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemCount: _categories.length,
padding: EdgeInsetsDirectional.only(start: 16, end: 12),
itemBuilder: (context, index) {
return InkWell(
onTap: () {},
child: Container(
height: 24,
alignment: Alignment.center,
child: Text(
categories[index].name,
),
),
);
},
)

Flutter : SingleChildScrollView doesn't work with columns and grid view. Why?

I can't scroll to see my lower grid view. Why is that? What should I change to make this work? Please help!!!
Thank you in advance.
Scaffold(
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Text('GridView 1'),
GridView.count(
crossAxisCount: 3,
shrinkWrap: true,
children: List.generate(
9,
(index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
);
},
),
),
Text('GridView 2'),
GridView.builder(
itemCount: list_item.length,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
// width: 150,
// height: 150,
);
},
),
],
),
),
),
);
Thank you for helping me in flutter.
It actually does work, just not the way you need it.
The problem is that GridView itself is a scrollable widget too. So when you try to scroll the page, it actually tries to scroll those GridViews and not the SingleChildScrollView.
To disable GridView scrolling ability - you need to add one more parameter.
GridView.count(
physics: NeverScrollableScrollPhysics(),
...
),
Try this:
Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[]
multiple gridview scrollable
Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Text('GridView 1'),
Container(
height: 400,
child: GridView.count(
crossAxisCount: 3,
shrinkWrap: true,
primary: false,
children: List.generate(
20,
(index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
);
},
),
),
),
Text('GridView 2'),
Container(
height: 400,
child: GridView.builder(
itemCount: 20,
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return TouchableImageCard(
imagePath: 'assets/images/view_${index + 1}.jpg',
// width: 150,
// height: 150,
);
},
),
),
],
),
),
);

How do i return expanded widgets from ListView.builder?

I have tried to return a list of widgets in horizontal direction, i want to expand widgets width dynamically. how can i achieve this. (Note: ListView.builder placed inside column)
ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: widget.playType.length,
itemBuilder: (BuildContext context, int index) {
return Flex(
direction: Axis.horizontal,
children: <Widget>[
Flexible(
child: InkWell(
onTap: () {},
child: Container(
padding: EdgeInsets.only(left: 10, right: 10),
color: colorSubMenuBg,
height: 45,
child: Align(
alignment: Alignment.center,
child: Text(
widget.playType[index],
style: CustomTextStyle.listTile4(context),
),
),
),
),
),
],
);
});
Expected output should be like this highlighted part:
Wrap Container( height: 70)in your ListViewBuilder()
like this
Container(
height: 70,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: widget.playType.length,
itemBuilder: (BuildContext context, int index) {
return Flex(
direction: Axis.horizontal,
children: <Widget>[
Flexible(
child: InkWell(
onTap: () {},
child: Container(
padding: EdgeInsets.only(left: 10, right: 10),
color: colorSubMenuBg,
height: 45,
child: Align(
alignment: Alignment.center,
child: Text(
widget.playType[index],
style: CustomTextStyle.listTile4(context),
),
),
),
),
),
],
);
}),
);```
Actual working code, i removed flex from ListView.builder and added width for ListItems and ListView.
var buttonListWidth = MediaQuery.of(context).size.width;
Container(
height: 45,
width: buttonListWidth,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: widget.playType.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
setState(() {});
},
child: Container(
color: colorSubMenuBg,
height: 45,
width: buttonListWidth / widget.playType.length,
child: Align(
alignment: Alignment.center,
child: Text(
widget.playType[index],
style: CustomTextStyle.listTile4(context),
),
),
),
);
}))
Try adding a Row over the ListView.builder and add mainAxisSize: MainAxisSize.min, property to that Row.
ItemExtent property of ListView.builder
itemExtent: MediaQuery.of(context).size.height / LENGHT,