Flutter: Make all screen scrollable with GridView.builder inside - flutter

In my home screen my app shows carousel first then a vertical list of challenges cards retrieved from Cloud Firestore using GridView.builder as follows:
GridView.builder(
scrollDirection: Axis.vertical,
itemCount: _challenges.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),
),
itemBuilder: (context, index) {
return InkWell(
onTap: () {
if (_challenges[index]["isLocked"] == "true") {
showLockedDialog();
} else {
checkParticipation(index);
if (checkPart == true) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
ChallengeDetails(_challenges[index])));
}
checkPart = true;
}
},
child: Stack(
children: [
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image(
image: NetworkImage(_challenges[index]["image-path"]),
fit: BoxFit.cover,
height: 150,
width: 350,
opacity: _challenges[index]["isLocked"] == "true"
? AlwaysStoppedAnimation(.4)
: null,
),
),
),
Center(
child: Text(
"${_challenges[index]["name"]}\n",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
Center(
child: Text(
"\n${_challenges[index]["date"]}",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
textDirection: TextDirection.ltr,
)),
Center(
child: SizedBox(
height: 130,
width: 130,
child: _challenges[index]["isLocked"] == "true"
? Image.asset("assets/lock-icon.jpg")
: null,
),
)
],
),
);
});
Everything retrieving fine and it is rendered in my home_screen as follows:
body: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
padding: const EdgeInsets.only(right: 8, left: 8, bottom: 5),
child: Row(
children: [
Text(
AppLocalizations.of(context)!.challenges + " ",
style: TextStyle(fontSize: 20),
),
Text(
AppLocalizations.of(context)!.clickToParticipate,
style: TextStyle(fontSize: 15),
)
],
),
),
Expanded(child: ChallengeCard()),
],
),
The problem is that only the GridView area is scrolling and what am seeking for is to scroll the whole screen with the GridView area, I was trying to use the CustomScrollView() but its not working properly.
I'll be thankful for any help.

First in your GridView.builder add these:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
...
)
then in your home_screen wrap your column with SingleChildScrollView:
SingleChildScrollView(
child: Column(
children: [
AdsBanner(),
SizedBox(
height: 30,
),
Padding(
...
),
),

You can provide physics: NeverScrollableScrollPhysics() on GridView to disable scroll effect. If you want scrollable as secondary widget use primary: false, to have Full Page scrollable, you can use body:SingleChildScrollView(..) or better using body:CustomScrollView(..)

Related

How to show ListView.builder with bloc

I want to showing list of items with ListView.builder, which wrap with BlocBuilder. My code is success connect to API, but the problem is I do not know how to display the items, instead the length of the items like picture below.
Here I attach the code:
SizedBox(
height: 350,
width: 290,
child: Padding(
padding: const EdgeInsets.only(left: 30, top: 20),
child: BlocBuilder<ExcavatorBloc, ExcavatorState>(
builder: (context, state) {
return ListView.builder(
itemCount: state.excavator.length,
itemBuilder: (context, index) {
return Row(
children: [
const SizedBox(
height: 10,
width: 10,
child: CircleAvatar(
foregroundColor:
ColorName.brandSecondaryGreen,
backgroundColor:
ColorName.brandSecondaryGreen,
),
),
const SizedBox(
width: 5,
),
Text(
state.excavator.length.toString(), //The problem is here----------
style: subtitle1(),
),
],
);
},
);
},
),
),
),
Instead of this
Text(
state.excavator.length.toString(),
style: subtitle1(),
),
use the index of the list builder
Text(
state.excavator?[index].attributeName ?? 'No value',
style: subtitle1(),
),

I Have An Issue In Grid View Builder

without building apk
when i dont build apk in flutter this type of gridview is build
and when i build apk this type of gridveiw list build in flutter
when apk is build
this is my code i want to build an apk so any one can fix this issue
i am getting this issue
while building an app in flutter
otherwise it is ok and give no issue but when i build this app i got error like this is gridview.builder and listview .builder also and i am using scaffold and in body i try everything but nothing work
here is my code
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Select Your City'),
Expanded(child: GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 20),
itemCount: serviceDataList.length,
itemBuilder: (ctx, i) {
// print(serviceDataList);
return GestureDetector(
onTap: () {
setState(() async {
if(isRedundentClick(DateTime.now())){
Fluttertoast.showToast(
msg: "hold on, processing",
toastLength: Toast.LENGTH_SHORT,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
return;
}else{
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('City_Id', serviceDataList[i]['city_id']);
prefs.setString('City_Name', serviceDataList[i]['city_name']);
prefs.setString('City_Lat', serviceDataList[i]['city_lat']);
prefs.setString('City_Long', serviceDataList[i]['city_long']);
print(serviceDataList[i]['city_id']);
print(serviceDataList[i]['city_name']);
int? rowsEffected2 = await dbHelper?.deletecart();
print(rowsEffected2);
Navigator.push(context, MaterialPageRoute(builder:(context)=>Navigation()));
}
});
},
child: Card(
elevation: 4,
color: Colors.white,
child: Column(
children: [
Container(
height: 210,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20)),
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
child: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ConstrainedBox(
constraints: new BoxConstraints(
// minHeight: 35.0,
maxHeight: 200.0,
),
child: Expanded(
child: Image.network(
serviceDataList[i]['city_img'] ?? '',
fit: BoxFit.fill,
),
),
),
// Row(
// children: [
// Text(
// 'Subtitle',
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 15,
// ),
// ),
// ],
// )
],
),
],
),
),
SizedBox(
height: 35,
child: Container(
color: Colors.grey.shade300,
child: Center(
child: Text(
serviceDataList[i]['city_name'],
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
)
),
);
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
mainAxisExtent: 264,
),
),)
])))
// bottomNavigationBar:Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// children: [
// SizedBox(
// height: 40,
// width: (MediaQuery.of(context).size.width/1.5),
// child: ElevatedButton(onPressed: (){Navigator.push(context, MaterialPageRoute(builder: (context)=> HomePage()),);
// }, child: Text('Save'))),
// ],
// )
);
pls help me with this code
Avoid wrapping your image within an Expanded widget when the parent is a ConstrainedBox. This is because the parent of the expanded widget cannot be a ConstrainedBox, which is an incorrect use of the parent widget. In debug mode, this will only display a warning, but in release mode, it will not render correctly.
Replace this:
ConstrainedBox(
constraints: new BoxConstraints(
// minHeight: 35.0,
maxHeight: 200.0,
),
child: Expanded(
child: Image.network(
serviceDataList[i]['city_img'] ?? '',
fit: BoxFit.fill,
),
),
),
With this:
ConstrainedBox(
constraints:
new BoxConstraints(
maxHeight: 200.0,
),
child: Image.network(
serviceDataList[i]['city_img'] ?? '',
fit: BoxFit.fill,
),
),

Extra "Space" In ListView and Card Flutter

I'm having this "extra space" on my first listview item that is a card being encapsulated in a container.
How do I remove it?
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(15.0),
height: 300,
child: Column(children: [
Row(children: [
Expanded(
child: Text("Lowest Fuel Price",
style: TextStyle(
fontWeight: FontWeight.w500,
color: Theme.orange3,
fontSize: 16.0)))
]),
Container(
height: 250,
child: Card(
elevation: 3,
child: ListView.builder(
itemCount: cheapest.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
final item = cheapest[index];
return Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
item.petrolType,
style: TextStyle(
color: Theme.gray1, fontSize: 18),
),
Text(
"\$" + item.petrolPrice,
style: TextStyle(
color: Theme.gray1, fontSize: 25),
),
Image(
fit: BoxFit.fill,
image: new AssetImage(
'assets/images/fuel_station/' +
item.petrolStation.toLowerCase() +
'.png')),
]),
index != cheapest.length - 1
? Divider(
color: Colors.grey,
)
: Divider(color: Colors.white)
],
);
})),
)
]));
}
https://api.flutter.dev/flutter/widgets/ListView-class.html
By default, ListView will automatically pad the list's scrollable extremities to avoid partial obstructions indicated by MediaQuery's padding. To avoid this behaviour, override with a zero-padding property.
Card(
elevation: 3,
child: MediaQuery.removePadding(
context: context,
removeTop: true,
child: ListView.builder(),
),
),

Flutter ListView Text show on multiLine if overflow

I have A listView in which I have another listview to show simple text in horizontal but the issue is its overflow on the left side If I give width to listview it's going to scroll list. I want if it's overflow then it will simply go to the next line instead of overflow or scroll.
My code
Expanded(
child: new ListView.builder(
itemCount: respondedData3['data'].length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
itemBuilder: (context, index) {
String TimeFormat = DateFormat("yyyy-MM-dd").format(DateTime.parse(respondedData3['data'][index]['appointmentDate']));
return Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Container(
child: GestureDetector(
onTap: () async {
Navigator.pop(context);
},
// onTap: widget.onPressed,
child: Stack(children: [
Container(
height: 80,
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
children: [
Text(TimeFormat, style: TextStyle(fontSize: 14, fontFamily: 'SegoeUI-Bold', color: kPrimaryColor)),
Text(respondedData3['data'][index]['appointmentTime'].toString(), style: TextStyle(fontSize: 13, fontFamily: 'SegoeUI', color: textGreyColor))
],
),
SizedBox(
width: 10,
),
Container(
color: Colors.grey,
height: 40,
width: 1.5,
),
SizedBox(
width: 10,
),
Column(
children: [
Text(respondedData3['data'][index]['serviceProviderName'].toString(), style: TextStyle(fontSize: 13, fontFamily: 'SegoeUI-Bold', color: textGreyColor)),
Container(
height: 20.0,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: serviceShow.length,
itemBuilder: (BuildContext context, int index) => Text('${serviceShow[index]["Name"]} ${serviceShow[index]["Time"]} ${serviceShow[index]["Price"]}'),
),
),
],
)
],
),
],
),
),
]),
),
),
);
},
),
)
You can see in the image it's showing an overflow error I need to show it in the second line.
ListView.builder(
itemCount: 3,
// respondedData3['data'].length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
itemBuilder: (context, index) {
String TimeFormat = "yyyy-MM-dd";
// DateFormat("yyyy-MM-dd").format(
// DateTime.parse(respondedData3['data'][index]['appointmentDate']));
return Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Container(
child: GestureDetector(
onTap: () async {
Navigator.pop(context);
},
// onTap: widget.onPressed,
child: Stack(children: [
Container(
height: 80,
// width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Column(
children: [
Text(
TimeFormat,
// style: TextStyle(
// fontSize: 14,
// fontFamily: 'SegoeUI-Bold',
// color: kPrimaryColor,
// ),
),
Text("Time"
// respondedData3['data'][index]
// ['appointmentTime']
// .toString(),
// style: TextStyle(
// fontSize: 13,
// fontFamily: 'SegoeUI',
// color: textGreyColor,
// ),
)
],
),
SizedBox(
width: 10,
),
Container(
color: Colors.grey,
height: 40,
width: 1.5,
),
SizedBox(
width: 10,
),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"serviceProviderName",
// respondedData3['data'][index]
// ['serviceProviderName']
// .toString(),
style: TextStyle(
fontSize: 13,
// fontFamily: 'SegoeUI-Bold',
// color: textGreyColor
),
),
Container(
height: 20.0,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 33,
itemBuilder:
(BuildContext context, int index) =>
Text(
'{serviceShow[index]["Name"]} {serviceShow[index]["Time"]} {serviceShow[index]["Price"]}',
),
),
),
],
),
),
],
),
],
),
),
]),
),
),
);
},
),
add max lines on your Text
Text(
'Your multiline text',
maxLines: 2, //2 or more line you want
overflow: TextOverflow.ellipsis,
),
),
You get this error because you don't tell specific width For displaying Text widget and your getting text is huge.Always remeber, in Text widget => use 'overflow: TextOverflow.ellipsis' . Because in dynamic application, text can be large
Use FittedBox to when you want to try your text in limited width. And you want not get overflow error, use "overflow: TextOverflow.ellipsis"
FittedBox(
child:
Container(
width: 260,
// height: 50,
child: const Text(
"testing1 testing2 testing3 testing4 testing5 testing6 testing7 testing8 testing9 testing10 testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing",
style: TextStyle(
// color: Colors.lightBlueAccent,
fontSize: 17,
fontWeight: FontWeight.w600,
),
maxLines: 4,
overflow: TextOverflow.ellipsis
),
),
)
The text in my app was overflowing too , and maxLines: 2, overflow: TextOverflow.ellipsis, was not working since the text was part of the Expanded(child: ListView.builder( so what I did was
LimitedBox(
maxWidth: 150,
child: Text(
videoInfo[index]["title"],
overflow: TextOverflow.clip,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
)
use Expanded up your Column example;
Expanded(child:
Column(
children: [
Text ('long text'),
Text ('long text 2')
]
)
);

Bottom overflowed inside column while listing with Grid.count

I have problem with column, inside Column i have 3 containers. 1st one has picture inside other two has text. For the first container i want to apply height like 100 for example. but max what can i apply is 60 then it giving bottom overflowed. I am using Grid.count to make grid view and listing them with List.genarate.
PS: Wrapping with expanded effecting first container height, and the container does not have fixed height
Here is my code :
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 90,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Theme.of(context).focusColor.withOpacity(0.9),
blurRadius: 4,
offset: Offset(0, 2)),
],
),
width: 90,
child: Hero(
tag: widget.heroTag + widget.product.id,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: CachedNetworkImage(
height: 90,
fit: BoxFit.fill,
imageUrl: this.widget.product.imageUrl,
placeholder: (context, url) => Image.asset(
'assets/img/loading.gif',
fit: BoxFit.cover,
height: 150,
),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
),
),
Center(
child: Container(
width: 90,
child: Text(
widget.product.name,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
),
),
Center(
child: Container(
child: Text(
" ${widget.product.salePrice.toString()} Ft ",
style: TextStyle(
color: Colors.blue[800],
fontSize: 13,
fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
),
),
)
],
),
Here i am listing them with grid.count and list.genearte :
GridView.count(
scrollDirection: Axis.vertical,
shrinkWrap: true,
primary: false,
mainAxisSpacing: 15.0,
// crossAxisSpacing: 4.0,
padding: EdgeInsets.symmetric(
vertical: 15),
crossAxisCount:
MediaQuery.of(context)
.orientation ==
Orientation.portrait
? 3
: 3,
children: List.generate(
_con.subCategories
.elementAt(0)
.products
.length, (index) {
return ProductGridItemWidget(
heroTag: 'product-grid' +
0.toString() +
index.toString(),
product: _con.subCategories
.elementAt(0)
.products
.elementAt(index),
onPressed: () {
{
_con.addToCart(_con
.subCategories
.elementAt(0)
.products
.elementAt(index));
}
});
}),
)),
Finally found solution from this post
Give a height to the child of GridView
Just need to write this line of code inside GridView.count
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 4),