space between items in gridview flutter - flutter

I have a gridview with 6 items (cards with images and text). I want those 6 items to fit me on the screen but the gridview leaves all the space I can between items by jumping 2 items off the screen.
I leave a picture of what I want and what I have.
Thank you.
return MaterialApp(
home: Scaffold(
body: Container(
margin: EdgeInsets.only(top: 0),
child: Stack(
alignment: AlignmentDirectional.topCenter,
children: <Widget>[
Container(
height: 200,
color: Colors.black,
),
Container(
margin: EdgeInsets.only(top: 200),
decoration: BoxDecoration(
image: new DecorationImage(
image: AssetImage("assets/fondo.png"), fit: BoxFit.fill)),
),
Image.asset("assets/cara_simio_banner.png"),
Padding(
padding: EdgeInsets.only(top: 220),
child: Text(
"{CodeJaVu}",
style: TextStyle(
color: Colors.white,
fontSize: 25,
fontWeight: FontWeight.bold),
),
),
Container(
margin: EdgeInsets.only(top: 230),
child: GridView.count(
crossAxisCount: 2,
children: items.map((item) {
return GestureDetector(
onTap: () {},
child: CardItem(item),
);
}).toList(),
),
)
],
),
)));
}
Widget CardItem(Item item) {
return Card(
margin: EdgeInsets.all(40),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Image.asset(
item.image,
width: 50,
height: 50,
),
Text(item.name)
],
)
);
}
class Item {
String _name;
String _image;
Item(this._name, this._image);
String get name => _name;
set name(String name) => _name = name;
String get image => _image;
set image(String image) => _image = image;
}
what I have,
what I want,

add childAspectRatio parametr to GridView.cout counstructor,
and change Card margin.
I've used:
..
GridView.count(
childAspectRatio: 3/2,
..
Card(
margin: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
..

You can also use mainAxisSpacing and crossAxisSpacing like below.
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisSpacing: 8, mainAxisSpacing: 4),
padding: EdgeInsets.all(8),
shrinkWrap: true,
itemCount: widgetList.length,
itemBuilder: (context, index) {
return widgetList[index];
},
);

Just add these 2 lines in your GridView widgets:
mainAxisSpacing: 20,
crossAxisSpacing: 20,

children:
space.photos.map((item) {
return Container(
margin: EdgeInsets.only(
left: 24,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
item,
width: 110,
height: 88,
fit: BoxFit.cover,
),
),
);
}).toList()

Related

Flutter GridView.builder how to put children symmetric

i use GridView.builder to build my catalog and my catalog looks bad, how can i put my grid symmetrically :
i want my catalog to look like this :
it is my GridView.builder code:
Widget buildCatalog(List<Product> product) => GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300,
childAspectRatio: 3 / 5,
crossAxisSpacing: 5,
mainAxisSpacing: 10),
itemCount: product.length,
itemBuilder: (context, index) {
final productItem = product[index];
final media = product[index].media?.map((e) => e.toJson()).toList();
final photo = media?[0]['links']['local']['thumbnails']['350'];
return Container(
padding: EdgeInsets.only(left: 15, right: 15, top: 10),
margin: EdgeInsets.symmetric(vertical: 8, horizontal: 10),
decoration: BoxDecoration(color: Colors.white,
borderRadius: BorderRadius.circular(20)),
child: Column(
children: <Widget>[
InkWell(
child: Container(
margin: EdgeInsets.all(8),
child:
// Image.network(productItem.media),
Image.network(media != null ? 'https://cdn.yiwumart.org/${photo}' : 'https://yiwumart.org/images/shop/products/no-image-ru.jpg'),
),
),
SizedBox(height: 10,),
Text(productItem.name, textAlign: TextAlign.center, style: TextStyle(fontSize: 20),),
Container(
width: MediaQuery.of(context).size.width * 0.8,
child: ElevatedButton(onPressed: () {}, child: Text('5000 тг')))
],
),
);
},
);
Try this:
Container(
padding: EdgeInsets.only(left: 15, right: 15, top: 10),
margin: EdgeInsets.symmetric(vertical: 8, horizontal: 10),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(20)),
child: Column(
children: <Widget>[
InkWell(
child: Container(
margin: EdgeInsets.all(8),
child:
// Image.network(productItem.media),
Image.network(media != null
? 'https://cdn.yiwumart.org/${photo}'
: 'https://yiwumart.org/images/shop/products/no-image-ru.jpg'),
),
),
SizedBox(
height: 10,
),
Text(
productItem.name,
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 20),
),
Spacer(),
Container(
width: MediaQuery.of(context).size.width * 0.8,
child: ElevatedButton(
onPressed: () {}, child: Text('5000 тг')))
],
),
),

GridView Flutter

i'm trying to do this page
but what i get is this
this is my code
SingleChildScrollView(
child: Column(
children: [
Center(
child: Container(
margin: EdgeInsets.all(20),
width: 230,
height: 40,
child: ElevatedButton(
onPressed: () {
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xff28CC61)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Add a book", style: TextStyle(
fontSize: 20
),),
),
),
),
),
Container(
child: Text("Explore between 10 books", style: TextStyle(
fontSize: 20
),),
),
Container(
//adding: EdgeInsets.all(12),
child: SingleChildScrollView(
child: GridView.builder(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1,
crossAxisSpacing: 20,
crossAxisCount: 2,
mainAxisSpacing: 8),
itemCount: books.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
width: 50,
height: 100,
child: Card(
color: Color(0xFFEDEDED),
child: Column(
children: [
Image.asset(books[index].image, height: 150
,
width: 150,fit: BoxFit.cover,),
],
),
),
);
}),
),
),
],
),
),
ignore the colors and styles i want how to do the page
i stucked on gridview and how to write text below the picture + How can I fix my code to do it? So each image has same size as others? i tried to see the grid view documentation and i could not find anything.
Change childAspectRatio : 1 to childAspectRatio:0.7. childaspectRatio defines the ratio between width and height of children. If you set it as 1 you will get a square shaped widget. More than 1 is horizontal rectangle and less than 1 gives vertical rectangle.

How to center grid button inside red container

I want to center all grid button inside red container but it is showing big space at bottom of red container..how to solve this
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.red,
height: MediaQuery.of(context).size.height*0.60,
width: MediaQuery.of(context).size.height*0.60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
itemCount: 16,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context,index)=>
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(child: Center(child: Text(index.toString(),)),color: Colors.blue,),
)
,),
),
),
);
}
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.red,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.height,
child: Center(
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.6,
child: GridView.builder(
padding: EdgeInsets.all(16),
itemCount: 16,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Center(
child: Text(
index.toString(),
)),
color: Colors.blue,
),
),
),
),
),
),
);
}
You can wrap the gridview.builder inside a sized box ( provided some height ) and wrap it under Center widget.
You can do it like this :
Center(
child: Container(
color: Colors.red,
height: MediaQuery.of(context).size.height * 0.60,
width: MediaQuery.of(context).size.height * 0.60,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column( // column
mainAxisAlignment: MainAxisAlignment.center, // center
children: [
Container( // if you don't have this container, there is an error
height: MediaQuery.of(context).size.height * 0.50, // new height
width: MediaQuery.of(context).size.height * 0.50, // new width
color: Colors.green,
child: GridView.builder(
padding: const EdgeInsets.all(0.0), // delete all padding from grid
itemCount: 20, // more items to scroll
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Center(
child: Text(
index.toString(),
)),
color: Colors.blue,
),
),
),
),
],
),
),
),
)
Enclose your Grid inside a Column to allow it to be centered, because if you don't do it I can't find another way to center it because the Grid is dynamic in height and could not be centered.
And with this, you delete the big space in the red container

flutter: how to scroll listview inside listview using a button

i have nested Listview.Builder inside my FutureBuilder one is scroll horizontally and one in vertically what i want is when i click on a button i want to scroll my horizontal listview i passed a ScrollController to horizontal listview but when i press the arrow all of horizontal listview scroll not of the index.
How Can i achieve that...
here i my code...
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 30, right: 10),
child: FutureBuilder<List<Catagory>>(
future: categoryList,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Catagory> model = snapshot.data!;
return ListView.builder(
itemCount: model.length,
itemBuilder: (context, index) {
List<Product> product =
model[index].products;
List<bool> scroll=List.generate(model.length, (index) => false);
return Column(
children: [
Row(
children: [
SizedBox(width: width * 0.5,
child: Text(model[index].name,
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
style: const TextStyle(
color: Colors.red,
fontSize: 16,
)),
),
SizedBox(width: 30),
Expanded(
child: Container(
height: 1,
color: Colors.grey,
)),
SizedBox(width: 40),
],
),
SizedBox(
height: 10,
),
Row(
children: [
Expanded(
child: Container(
width: width,
height: 140,
child: ListView.builder(
controller: _controller ,
scrollDirection: Axis.horizontal,
itemCount: model[index].products.length,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 80,
height: 130,
padding: EdgeInsets.only(right: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 70,
height: 70,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: primaryColor),
child: CachedNetworkImage(
imageUrl: product[index].img,
placeholder: (context, url) => const Center(
child: SizedBox(
width: 25,
height: 25,
child: CircularProgressIndicator())),
imageBuilder: (context, imageProvider) =>
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover),
),
),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
const SizedBox(height: 3,),
Text(product[index].name,
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
),
const SizedBox(height: 2,),
MyText(title: (product[index].salePrice != '') &&
(double.parse(product[index].salePrice) <
double.parse(product[index].regularPrice))
? product[index].salePrice
: product[index].regularPrice,
textColor: Colors.black54,
),
const SizedBox(height: 3,),
MyTextButton(
width: 55,
height: 24,
title: 'Añadir',
fontSize: 8,
textColor: Colors.white,
backgroundColor: primaryColor,
cornerRadius: 5,
onPress: () {
Navigator.push(context, MaterialPageRoute(builder: (context) =>
ProductType(product: product[index])));
})
],
),
);
}))),
InkWell(
onTap: () {
_animateToIndex(5);
// here when i press this i want to make horizontal list of specific index to scroll
},
child: Container(
height: 140,
width: 40,
child: Icon(
Icons.arrow_forward_ios,
color: Colors.grey),
),
)
],
),
SizedBox(
height: 10,
),
],
);
});
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Center(child: CircularProgressIndicator());
},
)))
My Animation Code...
final ScrollController _controller = ScrollController();
final double _height = 100.0;
void _animateToIndex(int index) {
_controller.animateTo(
index * _height,
duration: Duration(seconds: 5),
curve: Curves.fastOutSlowIn,
);
}
i'm new to flutter i research too much but i didn't found any solution i have to submit this project please help me as soon as possible thanks in advance...

Why I'm not able to get the updated variable even using setstate inside the stateful widget. As I want to update my Container on new TabBar option

Basically I want to change content on selecting the TabBar options. Here's my code. Also I'm new to flutter. I've also created a _incrementCounter() and getter setter methods. By using _incrementCounter() I'm returning an integer in order to update the PAgeView of my screen which is implemented inside a List called tabsCat. But on calling the _incrementCounter() method on line 264 it does not give the updated value please guide.
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttertravelapp/models/beach_model.dart';
import 'package:fluttertravelapp/models/new_category_model.dart';
import 'package:fluttertravelapp/models/popular_model.dart';
import 'package:fluttertravelapp/models/recommended_model.dart';
import 'package:fluttertravelapp/screens/selected_category_screen.dart';
import 'package:fluttertravelapp/screens/selected_place_screen.dart';
import 'package:fluttertravelapp/widgets/bottom_navigation_bar.dart';
import 'package:fluttertravelapp/widgets/custom_tab_indicator.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int count = 0;
// Creating the getter method
// to get input from Field/Property
int get getCount {
return count;
}
// Creating the setter method
// to set the input in Field/Property
set setCount(int newCount) {
count = newCount;
}
int _incrementCounter() {
int index = 0;
setState(() {
index = getCount;
print(index);
});
return index;
}
/// Page Controller
final _pageController = PageController(viewportFraction: 0.877);
#override
Widget build(BuildContext context) {
int tabIndex = 0;
List tabsCat = [
PageView(
physics: BouncingScrollPhysics(),
controller: _pageController,
scrollDirection: Axis.horizontal,
children: List.generate(
recommendations.length,
(int index) => GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SelectedCategoryScreen(
newCategoryModel: newCategories[index])));
},
child: Container(
margin: EdgeInsets.only(right: 28.8),
width: 333.6,
height: 218.4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9.6),
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage(newCategories[index].image),
),
),
child: Stack(
children: <Widget>[
Positioned(
bottom: 19.2,
left: 19.2,
child: ClipRRect(
borderRadius: BorderRadius.circular(4.8),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaY: 19.2, sigmaX: 19.2),
child: Container(
height: 36,
padding: EdgeInsets.only(
left: 16.72, right: 14.4),
alignment: Alignment.centerLeft,
child: Row(
children: <Widget>[
SvgPicture.asset(
'assets/svg/icon_location.svg'),
SizedBox(
width: 9.52,
),
Text(
recommendations[index].name,
style: GoogleFonts.lato(
fontWeight: FontWeight.w700,
color: Colors.white,
fontSize: 16.8),
)
],
),
),
),
),
)
],
),
),
),
),
),
PageView(
physics: BouncingScrollPhysics(),
controller: _pageController,
scrollDirection: Axis.horizontal,
children: List.generate(
recommendations.length,
(int index) => GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SelectedCategoryScreen(
newCategoryModel: newCategories[index])));
},
child: Container(
margin: EdgeInsets.only(right: 28.8),
width: 333.6,
height: 218.4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9.6),
image: DecorationImage(
fit: BoxFit.cover,
image: CachedNetworkImageProvider(recommendations[index].image),
),
),
child: Stack(
children: <Widget>[
Positioned(
bottom: 19.2,
left: 19.2,
child: ClipRRect(
borderRadius: BorderRadius.circular(4.8),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaY: 19.2, sigmaX: 19.2),
child: Container(
height: 36,
padding: EdgeInsets.only(
left: 16.72, right: 14.4),
alignment: Alignment.centerLeft,
child: Row(
children: <Widget>[
SvgPicture.asset(
'assets/svg/icon_location.svg'),
SizedBox(
width: 9.52,
),
Text(
recommendations[index].name,
style: GoogleFonts.lato(
fontWeight: FontWeight.w700,
color: Colors.white,
fontSize: 16.8),
)
],
),
),
),
),
)
],
),
),
),
),
),
];
return Scaffold(
//bottomNavigationBar: BottomNavigationBarTravel(),
body: SafeArea(
child: Container(
child: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
/// Custom Navigation Drawer and Search Button
Container(
height: 57.6,
margin: EdgeInsets.only(top: 28.8, left: 28.8, right: 28.8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
],
),
),
/// Text Widget for Title
Padding(
padding: EdgeInsets.only(top: 0, left: 28.8),
child: Text(
'Explore\nPakistan',
style: GoogleFonts.playfairDisplay(
fontSize: 45.6, fontWeight: FontWeight.w700),
),
),
/// Custom Tab bar with Custom Indicator
Column(
children:
[DefaultTabController(
length: 4,
child: TabBar(
labelPadding: EdgeInsets.only(left: 14.4, right: 14.4),
indicatorPadding:
EdgeInsets.only(left: 14.4, right: 14.4),
isScrollable: true,
labelColor: Color(0xFF000000),
unselectedLabelColor: Color(0xFF8a8a8a),
labelStyle: GoogleFonts.lato(
fontSize: 14, fontWeight: FontWeight.w700),
unselectedLabelStyle: GoogleFonts.lato(
fontSize: 14, fontWeight: FontWeight.w700),
indicator: RoundedRectangleTabIndicator(
color: Color(0xFF000000), weight: 2.4, width: 14.4),
onTap: (index){
setCount = index;
//print(getCount);
},
tabs: [
Tab(
child: Container(
child: Text('Recommended'),
),
),
Tab(
child: Container(
child: Text('Popular'),
),
),
Tab(
child: Container(
child: Text('New Destination'),
),
),
Tab(
child: Container(
child: Text('Hidden Gems'),
),
)
]),
),
/// ListView widget with PageView
/// Recommendations Section
Container(
height: 218.4,
margin: EdgeInsets.only(top: 16),
child: tabsCat[_incrementCounter()],
),
]),
/// Dots Indicator
/// Using SmoothPageIndicator Library
Padding(
padding: EdgeInsets.only(left: 28.8, top: 28.8),
child: SmoothPageIndicator(
controller: _pageController,
count: recommendations.length,
effect: ExpandingDotsEffect(
activeDotColor: Color(0xFF8a8a8a),
dotColor: Color(0xFFababab),
dotHeight: 4.8,
dotWidth: 6,
spacing: 4.8),
),
),
/// Text Widget for Popular Categories
Padding(
padding: EdgeInsets.only(top: 48, left: 28.8, right: 28.8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width*0.4,
child: FittedBox(
child: Text(
'Popular Categories',
style: GoogleFonts.playfairDisplay(
fontWeight: FontWeight.w700,
color: Color(0xFF000000),
),
),
),
),
Container(width: MediaQuery.of(context).size.width*0.1,
child: FittedBox(
child: Text(
'Show All ',
style: GoogleFonts.lato(
fontWeight: FontWeight.w500,
color: Color(0xFF8a8a8a),
),
),
),
)
],
),
),
/// ListView for Popular Categories Section
Container(
margin: EdgeInsets.only(top: 33.6),
height: 45.6,
child: ListView.builder(
itemCount: populars.length,
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
padding: EdgeInsets.only(left: 28.8, right: 9.6),
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.only(right: 19.2),
height: 45.6,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9.6),
color: Color(populars[index].color),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
width: 19.2,
),
Image.asset(
populars[index].image,
height: 16.8,
),
SizedBox(
width: 19.2,
)
],
),
);
},
),
),
/// ListView for Beach Section
Container(
margin: EdgeInsets.only(top: 28.8, bottom: 16.8),
height: 124.8,
child: ListView.builder(
itemCount: beaches.length,
padding: EdgeInsets.only(left: 28.8, right: 12),
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return Container(
height: 124.8,
width: 188.4,
margin: EdgeInsets.only(right: 16.8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(9.6),
image: DecorationImage(
fit: BoxFit.cover,
image:
CachedNetworkImageProvider(beaches[index].image),
),
),
);
},
),
)
],
),
),
),
);
}
}
Solve the error by calling the _incrementcounter method onto OnTap section. Here's my code changes:
Edited incrementcounter method and declare new method setNewCount,
void setNewCount(int newCount) {
count = newCount;
}
void _incrementCounter() {
setState(() {
count = getCount;
});
}
2nd change :
onTap: (index){
setNewCount(index);
_incrementCounter();
},
3rd change:
Container(
height: 218.4,
margin: EdgeInsets.only(top: 16),
child: tabsCat[count],
),
Try
onTap: (index){
setCount(index);
//print(getCount);
},
instead of
onTap: (index){
setCount = index;
//print(getCount);
},