I am using TabBarView and in children, I have GridView.List(), when I Use Expand(), it gives me the error of
Failed assertion: line 544 pos 12: ‘child.hasSize’: is not true.
I used NestedScrollView with SliverToBoxAdapter but then I get a strange padding from the top, here is my build method
Widget build(BuildContext context) {
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return Container(
height: h,
padding: const EdgeInsets.only(
left: 12,
right: 0,
top: 25,
),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 40,
),
InkWell(
onTap: () {
router.push(
SearchList.routeName,
);
},
child: Container(
margin: const EdgeInsets.only(
right: 12,
),
padding: const EdgeInsets.symmetric(vertical: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
border: Border.all(
color: const Color(0xffE8E8E8),
),
),
child: Row(
children: [
const SizedBox(width: 20),
SvgPicture.asset('svg/search.svg'),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Where are you travelling next?',
style:
Theme.of(context).textTheme.labelSmall!.copyWith(
color: const Color(0xff000000),
fontFamily: 'OverUsed',
fontSize: 16,
fontWeight: FontWeight.w400,
),
),
const Text(
"Anywhere, 30 Days plans",
style: TextStyle(
fontSize: 11,
color: Color(0xffA0A4A8),
fontFamily: 'OverUsed',
),
),
],
),
],
),
),
),
SizedBox(
height: 30,
),
TabBar(
controller: _tabController,
isScrollable: true,
tabAlignment: TabAlignment.start,
indicator: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.transparent,
width: 0.0,
),
),
),
dividerHeight: 0,
labelPadding: const EdgeInsets.symmetric(
horizontal: 5,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
tabs: [
countriesTabContainer(context,
text: "Popular 🔥", isSelected: selectedIndex == 0),
countriesTabContainer(context,
text: "Destinations", isSelected: selectedIndex == 1),
countriesTabContainer(context,
text: "Regions", isSelected: selectedIndex == 2),
],
onTap: (int index) {
setState(() {
selectedIndex = index;
_tabController?.animateTo(index);
});
},
),
Flex(direction: Axis.vertical, children: [
TabBarView(
controller: _tabController,
children: [
ProductsGrid(
type: ProductType.popular,
),
ProductsGrid(
type: ProductType.country,
),
ProductsGrid(
type: ProductType.region,
),
],
),
]),
],
),
),
);
}
This is my Product Grid
Widget build(BuildContext context) {
var data = context.watch<ProductsListProvider>().byType(widget.type);
return GridView.builder(
itemCount: data.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.78,
),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(
right: 8.0,
bottom: 8.0,
),
child: TileCard(
horizontal: 0,
elevation: 1,
radius: 13.4,
onTap: () {
router.push(PlansPage.routeName, extra: data[index]);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
Align(
alignment: Alignment.center,
child: NetworkImageWithPlaceholder(
data[index].imageUrl,
circular: false,
width: 193,
height: 164,
radius: 12,
),
),
Positioned(
top: 8,
left: 8,
child: NetworkImageWithPlaceholder(
data[index].flag,
height: 40,
width: 40,
circular: true,
),
),
],
),
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
data[index].name,
maxLines: 1,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w500,
fontFamily: 'OverUsed',
),
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Row(
children: [
Text(
"Starting from: ",
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.grey,
fontFamily: 'OverUsed',
fontSize: 12,
fontWeight: FontWeight.w400,
),
),
Text(
"$6.00 USD",
style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: Colors.black,
fontWeight: FontWeight.w500,
fontFamily: 'OverUsed',
fontSize: 14,
),
),
],
),
),
],
),
),
);
},
);
}
This is the screenshot from NestedScrollView
2
ok, so the answer is that when you do shrinkWrap: true
, it adds SliverPaddingProperty to the GridView or ListView, in order to remove this padding, wrap your widget in MediaQuery.removePadding() where you are using shrinkwraping, here is the example
Widget build(BuildContext context) {
var data = context.watch<ProductsListProvider>().byType(widget.type);
return MediaQuery.removePadding(
context: context,
removeTop: true,
child: GridView.builder(
itemCount: data.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.82,
),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return Container();
},
),
);}