i am working on this flutter app where i need to show the children in a grid view, so i used a column widget in side GridView.builder like shown below, i want to remove the sapcing where its marked in the red, and leave it to be responsive somehow...
GridView widget:
GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
crossAxisSpacing: 10,
mainAxisSpacing: 10,
maxCrossAxisExtent: 450,
),
primary: false,
shrinkWrap: true,
padding: const EdgeInsets.only(
right: 25,
left: 25,
top: 20,
),
itemCount: data.length,
itemBuilder: (ctx, index) {
return VideoWidget(
oneVideoData: data[index],
);
},
),
VideoWidget:
Container(
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(
...
),
child: Row(
children: [
...
],
),
),
Stack(
alignment: AlignmentDirectional.center,
children: [
_videoPlayerControllerFFrame.value.isInitialized
? AspectRatio(
aspectRatio:
_videoPlayerControllerFFrame.value.aspectRatio,
child: VideoPlayer(
_videoPlayerControllerFFrame,
),
)
: Container(
height: 250,
),
_isVideoLoading
? const CircularProgressIndicator(
color: Colors.yellow,
)
: IconButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return VideoPlayerWidget(
oneVideoData: widget.oneVideoData,
videoController: _videoPlayerController,
);
});
},
icon: Icon(
Icons.play_arrow,
color: Theme.of(context).colorScheme.tertiary,
size: 50,
),
),
],
),
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
...
),
),
],
),
);
this a screen shot of the output:
i want to get rid of the red space in the bottom.
Thanks in advance
Try below code hope its help to you.
GridView.builder(
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 6,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 5,
shadowColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
10,
),
),
margin: EdgeInsets.all(5),
child: Container(
height: 200,
width: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: EdgeInsets.all(2),
child: Row(
children: [
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.black,
width: 1.0,
),
),
child: CircleAvatar(
radius: 20,
backgroundImage: NetworkImage(
'https://miro.medium.com/max/1400/1*-6WdIcd88w3pfphHOYln3Q.png',
),
),
),
SizedBox(
width: 10,
),
Text('Person ${index.toString()}'),
],
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://miro.medium.com/max/1400/1*-6WdIcd88w3pfphHOYln3Q.png',
),
),
),
),
),
Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.yellow,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10.0),
bottomRight: Radius.circular(10.0),
),
),
child: Text(
'Awesome Product From Person ${index.toString()}',
),
),
],
),
),
);
},
),
Result Screen->
Related
I am trying to make the following design:
I am using Firebase as my backend as a service, and I am having trouble having my code work. There are no errors, but the UI visual looks funky.. I'm trying to create a GridView.builder() and display a grid of my UI (Designs provided below), but the image isn't working as it should be.. You'll see that the light blue is the background color, and the image should be covering the entire cell, even behind the container with the text widget. Check out the code:
return GridView.builder(
shrinkWrap: true,
itemCount: locations.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 37,
crossAxisSpacing: 37,
),
itemBuilder: (context, index) {
Location location = locations[index];
return MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
child: Container(
decoration: BoxDecoration(
color: blue100,
borderRadius: BorderRadius.circular(
20,
),
),
child: Stack(
children: [
ClipRRect(
child: Image.network(
location.image,
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(20),
),
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(
color: isLight
? Color(0xFFF2F2F2)
: Colors.black,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(
20,
),
bottomRight: Radius.circular(
20,
),
),
),
height: isSmall ? 44 : 67,
child: Center(
child: CustomText(
text: locations[index].street,
size: isSmall ? 12 : 15,
),
),
),
],
),
),
],
),
),
),
);
},
);
Here is what this code causes:
You can obviously see that the code is there, and the general thing is working, although the image doesn't want to cooperate and resizes itself differently.
Why is this? Is it something with the GridView..?
I have try this without Stack also, refer below code hope its help to you. add some changes in my code with your code like image and text add below design code inside GridView.builder()
Card(
elevation: 5,
shadowColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
20,
),
),
margin: EdgeInsets.all(5),
child: Container(
height: 200,
width: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(
10,
),
topRight: Radius.circular(
10,
),
),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://miro.medium.com/max/1400/1*-6WdIcd88w3pfphHOYln3Q.png',
),
),
),
),
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20.0),
bottomRight: Radius.circular(20.0),
),
),
child: Text(
'300 E Mejor Dr.',
),
),
],
),
),
),
Result Screen->
we can use stack like this inside gridviewbuilder()
GridView.builder(
padding: const EdgeInsets.all(10),
itemCount: itemProvider.sitem.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: (context, index) => Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: GestureDetector(
onTap: () {},
child: Stack(
children: [
Container(
child: Center(
child: Image.network(
itemProvider.sitem[index].imageURL.toString(),
fit: BoxFit.fill,
),
)),
Positioned(
top: 10,
left: 20,
child: Text('${itemProvider.sitem[index].name}'))
],
),
),
I have no idea how to change the state of my grid view when a button is clicked can someone help me with this?
So, I have this textButton that should change the state of my grid view when clicked but I have no idea how to implement it. Below is my code.
From the image attached, when water, food, school etc are clicked the gridview should only provide specific organizations..
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(20.0),
child: ListView(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Container(
padding: const EdgeInsets.only(left: 20, right: 20),
height: SizeConfig.screenHeight / 6.5,
color: kPrimaryColor,
child: Row(
children: [
const CircleAvatar(
radius: 40,
backgroundImage: AssetImage(
'assets/images/SDG Wheel_Transparent_WEB.png'),
),
const SizedBox(
width: 10,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Donate Today!",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontFamily: "Quicksand",
decoration: TextDecoration.none),
),
SizedBox(
height: 5,
),
Text(
"Small contributions quickly\nadd up if enough people\ntake up the cause.",
style: TextStyle(
color: Colors.white,
fontSize: 12,
decoration: TextDecoration.none),
),
],
),
Expanded(child: Container()),
Container(
width: 70,
height: 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Color(0xFFf3fafc)),
child: Center(
child: IconButton(
icon: SvgPicture.asset("assets/icons/give.svg"),
onPressed: () {},
color: Color(0xFF69c5df),
//size: 30,
),
),
),
],
),
),
),
SizedBox(
height: 30,
),
const Align(
alignment: Alignment.centerLeft,
child: Text(
"Select your desired organisation to donate.",
style: TextStyle(
color: Color(0xFF1f2326),
fontSize: 15,
decoration: TextDecoration.none),
),
),
const Divider(color: Colors.black38),
//here is the textButton
Container(
height: 50,
width: double.infinity,
color: Colors.white,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
for (int i = 0; i < categories.length; i++)
Container(
width: 90,
padding: const EdgeInsets.only(left: 4.0, right: 4.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: kPrimaryColor,
),
child: TextButton(
onPressed: () {}, //here i need a way to change the state of
the grid view
child: Text(categories[i],
style: TextStyle(color: Colors.white)),
),
),
),
],
),
),
),
const Divider(color: Colors.black38),
const SizedBox(
height: 30,
),
GridView.count(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
children: _listItem
.map((item) => Card(
color: Colors.transparent,
elevation: 0,
child: GestureDetector(
onTap: () => Navigator.pushNamed(context, item.route),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: AssetImage(item.image),
fit: BoxFit.cover)),
)),
))
.toList(),
)
],
),
);
}
}
Thanks very much.
The simplest things to do is to Filter your items based on selection by using the .where of Iterable https://api.flutter.dev/flutter/dart-core/Iterable/where.html
Basically when you push your Text button you store the type in a variable (you need a StatefulWidget for that)
then you can use where to filter your _listItem
GridView.count(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
children: _listItem
.where((element) {
//if your element is included return true else false
return true;
})
.map((item) => Card(
color: Colors.transparent,
elevation: 0,
child: GestureDetector(
onTap: () => Navigator.pushNamed(context, item.route),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: AssetImage(item.image),
fit: BoxFit.cover)),
)),
))
.toList(),
)
You can check a sample here for the behavior on the button:
https://dartpad.dev/49f2e4818d933c75a0e6ed1d47a836d2
I am trying to implement a vision board. I'm using gridview.builder for adding up to 12 images. Almost everything works as I expect: adding up to 12 images, but when the limit is reached, somehow I want to stop the iteration, because I am not able to return null, and any widget I return, it will create additional space I don't want.
GridView.builder(
clipBehavior: Clip.none,
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: SizeConfig.screenWidth!/3,
crossAxisSpacing: 0,
mainAxisSpacing: 0),
itemCount: visions.length+1,
itemBuilder: (BuildContext ctx, index) {
print("__________");
print("AM INTRAT IN ITEM BUILDER");
print("INDEX $index");
print(visions.length);
if (index < visions.length) {
print("PHOTO ALREADY ADDED CONTAINER");
return Stack(
alignment: Alignment.center,
children: [
Container(
width: double.infinity,
height: double.infinity,
),
Container(
width: SizeConfig.screenWidth!/4,
height: SizeConfig.screenWidth!/4,
decoration: BoxDecoration(
image: DecorationImage(
image: FileImage(File(visions[index])),
fit: BoxFit.cover),
borderRadius: const BorderRadius.all(
Radius.circular(
5.0) // <--- border radius here
),
),
),
Positioned(
top:0,
right:0,
child: Container(
child: ClipOval(
child: InkWell(
onTap: () {
_removeVisions(index);
},
child: Container(
padding: const EdgeInsets.all(5),
color: Colors.white,
child:
const Icon(
Icons.delete,
size: 16,
color: Color(0xff221F1E)),
),
),
),
),
),
],
clipBehavior: Clip.none,
);
}
else if(index<12){
print("ADAUGA POZA");
print("INDEX $index");
print(visions.length);
return InkWell(
onTap: () {
_openGallery(context);
},
child:
Stack(
alignment: Alignment.center,
children:[
Container(
width: SizeConfig.screenWidth!/4,
height: SizeConfig.screenWidth!/4,
decoration:
BoxDecoration(
border: Border.all(color: const Color(0xff221F1E)),
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
),
child:
const Icon(
Icons.add,
size: 22,
color: Color(0xff221F1E),
)
),
],
),
);
}
else {
return Container(color: Colors.red);
}
}
),
I want to remove that red container.
I have also tried to hardcode something with Positioned widget, but nothing worked, so I am trying somehow to exit when index is equal to 12 or any other solution...
I would try a true/false statement like this for your itemcount:
itemCount: (visions.length == 12) ? visions.length : visions.length + 1,
Yes, you can't return a null value but you can simply empty the widget. So, what I mean, SizedBox widget. Added an example for you, just check it
GridView.builder(
clipBehavior: Clip.none,
physics: ScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: SizeConfig.screenWidth!/3,
crossAxisSpacing: 0,
mainAxisSpacing: 0),
itemCount: visions.length+1,
itemBuilder: (BuildContext ctx, index) {
print("__________");
print("AM INTRAT IN ITEM BUILDER");
print("INDEX $index");
print(visions.length);
if (index < visions.length) {
print("PHOTO ALREADY ADDED CONTAINER");
return Stack(
alignment: Alignment.center,
children: [
Container(
width: double.infinity,
height: double.infinity,
),
Container(
width: SizeConfig.screenWidth!/4,
height: SizeConfig.screenWidth!/4,
decoration: BoxDecoration(
image: DecorationImage(
image: FileImage(File(visions[index])),
fit: BoxFit.cover),
borderRadius: const BorderRadius.all(
Radius.circular(
5.0) // <--- border radius here
),
),
),
Positioned(
top:0,
right:0,
child: Container(
child: ClipOval(
child: InkWell(
onTap: () {
_removeVisions(index);
},
child: Container(
padding: const EdgeInsets.all(5),
color: Colors.white,
child:
const Icon(
Icons.delete,
size: 16,
color: Color(0xff221F1E)),
),
),
),
),
),
],
clipBehavior: Clip.none,
);
}
else if(index<12){
print("ADAUGA POZA");
print("INDEX $index");
print(visions.length);
return InkWell(
onTap: () {
_openGallery(context);
},
child:
Stack(
alignment: Alignment.center,
children:[
Container(
width: SizeConfig.screenWidth!/4,
height: SizeConfig.screenWidth!/4,
decoration:
BoxDecoration(
border: Border.all(color: const Color(0xff221F1E)),
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
),
child:
const Icon(
Icons.add,
size: 22,
color: Color(0xff221F1E),
)
),
],
),
);
}
else {
return const SizedBox.shrink();
}
}
),
I want to do my interface like the image I show. I want to display the image the put a container to over the image. Now I have a problem with the ListTile I want to show did not come out.
Here is my code:
Scaffold(
appBar: AppBar(
title: Text('Detail'),
),
body: Column(children: <Widget>[
Expanded(
child:
Stack(children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(40), topRight: Radius.circular(40)),),
child: Image.assets('images/photo.png'),
),
Container(
margin: EdgeInsets.only(top: 170),
child: Stack(alignment: Alignment.topCenter, children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(40), topRight: Radius.circular(40)),
color: Colors.white),
)
],
),
),
Positioned(top: 200, left: 8,
child: Column(children: <Widget>[
ListTile(title: Text('Title'), subtitle: Text(''),)
],)
)
],
),
)
],)
);
Anyone can help me?
when scrolling inside Positioned widget you have to give all the positions and scroll direction in listview
Positioned(
top: 190,
bottom: 0,
right: 0,
left: 0,
child: SizedBox(
child: Container(
width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height- 190,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft:Radius.circular(20), topRight:Radius.circular(20)) ),
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: 20,
itemBuilder: (BuildContext context, int index){
return ListTile(title: Text("Title $index"),);
},
physics: AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
) ,),
),
)
Replace you code like this
return Scaffold(
appBar: AppBar(
title: Text("title text"),),
body: Stack(children: <Widget>[
Positioned(
top: 0,
child: Image.network("https://upload.wikimedia.org/wikipedia/commons/6/6d/Good_Food_Display_-_NCI_Visuals_Online.jpg",
fit: BoxFit.cover,
height: 200,
width: MediaQuery.of(context).size.width,
),
),
Positioned(
top: 190,
child: Container(
width: MediaQuery.of(context).size.width,
height: 600,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(topLeft:Radius.circular(20), topRight:Radius.circular(20)) ),
child: ListView(
shrinkWrap: true,
children: <Widget>[
ListTile(title: Text("Title 1"),),
ListTile(title: Text("Title 1"),),
ListTile(title: Text("Title 1"),),
],) ,),
)
],),
);
I have this design where the images i provide autoscroll everytime,it's working fine,but when i try to overlap with the textfield so the textfield should be in between of the image as Stacked ,i tried with stack,but the textfield doesn't move to top,there is the Screenshot what i am getting,please help me on this
This is what i am getting
Code
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
height: 180,
width: double.infinity,
child: Swiper(
itemBuilder: (BuildContext context, int index) {
return new Image.asset(
'assets/images/banner1.jpeg',
width: double.infinity,
fit: BoxFit.fitWidth,
);
},
itemCount: 3,
pagination: new SwiperPagination(
margin: new EdgeInsets.only(right: 200, bottom: 20)),
control: new SwiperControl(),
autoplay: true,
),
),
Padding(
padding: EdgeInsets.only(top: 0, left: 30, right: 30),
child: TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orangeAccent[200], width: 4.0),
borderRadius: const BorderRadius.all(
const Radius.circular(30.0),
),
),
),
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
height: 110,
width: size.width,
child: ListView.builder(
shrinkWrap: true,
itemCount: 10,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
width: 100,
height: 100,
color: Colors.yellow,
),
);
},
),
),
],
),
),
],
),
],
),
),
),
);
Currently, TextField is inside COlumn that's why it appears below the image, you have to remove that code and add in stack list,
Example:
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
height: 180,
width: double.infinity,
child: new Image.asset(
'assets/images/image.jpg',
width: double.infinity,
fit: BoxFit.fitWidth,
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
height: 110,
width: 40,
child: ListView.builder(
shrinkWrap: true,
itemCount: 10,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
width: 100,
height: 100,
color: Colors.yellow,
),
);
},
),
),
],
),
),
],
),
Padding(
padding: EdgeInsets.only(left: 30, right: 30, top: 150),
child: TextField(
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orangeAccent[200], width: 4.0),
borderRadius: const BorderRadius.all(
const Radius.circular(30.0),
),
),
),
),
),
],
),
),
),
);