Getting type 'Null' is not a subtype of type 'BuildContext' while trying to push data from one flutter screen to another - flutter

Here's widget.dart
Widget wallpapersList({required List<WallpaperModel> wallpapers, context}) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: GridView.count(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
crossAxisCount: 2,
childAspectRatio: 0.6,
mainAxisSpacing: 6.0,
crossAxisSpacing: 6.0,
children: wallpapers.map((wallpaper) {
return GridTile(
child: GestureDetector(
onTap: () {
print(wallpaper.src!.portrait); // printing successfully
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageView(wallpaper.src!.portrait),
));
},
child: Hero(
tag: wallpaper.src?.portrait ??
"https://www.pexels.com/photo/brown-grass-field-near-body-of-water-under-white-clouds-14491698/",
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
wallpaper.src?.portrait ??
"https://www.pexels.com/photo/brown-grass-field-near-body-of-water-under-white-clouds-14491698/",
fit: BoxFit.cover,
),
),
),
),
));
}).toList(),
),
);
}
Here's image_view.dart
class ImageView extends StatefulWidget {
String imgUrl;
ImageView(this.imgUrl);
#override
State<ImageView> createState() => _ImageViewState();
}
class _ImageViewState extends State<ImageView> {
#override
Widget build(BuildContext context) {
print(widget.imgUrl);
return Scaffold(
body: Stack(
children: [
Hero(
tag: widget.imgUrl,
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Image.network(
widget.imgUrl,
fit: BoxFit.cover,
)),
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0x36FFFFFF), Color(0x0FFFFFFF)])),
child: Column(children: [Text("Download backpaper")]),
),
Text(
"Back",
style: TextStyle(color: Colors.white),
)
],
),
);
}
}
Getting this error:
════════ Exception caught by gesture ═══════════════════════════════════════════
type 'Null' is not a subtype of type 'BuildContext'
════════════════════════════════════════════════════════════════════════════════
I searched the web & it mentioned that the value we are trying to push to another screen might be null but that's not the case here. What could be causing this error?

It must mean that you are calling wallpapersList without giving it a context.
Note that the signature is
wallpapersList({required List<WallpaperModel> wallpapers, context})
I strongly suggest to change it to
wallpapersList({required List<WallpaperModel> wallpapers, required BuildContext context})
Giving it an explicit type and also making it required. It would probably then point you exactly to the spot where you are using it without context.
This context must be given because it's the context used here:
Navigator.push(
context,
The error you are having is about this context being null, which is the context parameter of wallpapersList

Related

flutter: how to make reusable gridView widget

I have a gridview widget but I want to make it re usable so I can reuse it in many places without writing it again and again.
I have write it but I am facing one issue,
here is the widget i have written,
class GridViewSelection extends StatelessWidget {
GridViewSelection(
{super.key,
required this.menuList,
required this.onTap,
this.imageList,
this.nameList,});
VoidCallback onTap;
int menuList;
List? imageList;
List? nameList;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(15),
child: GridView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, mainAxisSpacing: 10, crossAxisSpacing: 10),
itemCount: menuList,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: onTap,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SvgPicture.asset(
imageList![index],
fit: BoxFit.contain,
width: MediaQuery.of(context).size.width * 0.15,
),
const SizedBox(
height: 10,
),
Text(
textAlign: TextAlign.center,
nameList![index],
style: TextStyle(
fontSize: 14,
color: AppTheme.colors.greyFontColor),
),
]),
),
),
);
}));
}
}
the issue i am facing is, I have a list in which i have defined the name and image for the grid view. the problem is, how will i use that list. this is how I am reusing the widget but it throws an error.
GridViewSelection(
menuList: oldMenu.length,
imageList: oldMenu,
nameList: oldMenu,
onTap: (){}),
I can not use it like this but its says that [index] is not defined for the list.
GridViewSelection(
menuList: oldMenu.length,
imageList: oldMenu[index].image,
nameList: oldMenu[index].name,
onTap: (){}),
any help is highly appreciated.
The constructor of GridViewSelection requires List? for names and images but you are trying to supply one element. In order to fix this, you will have to extract a list of name and image each, from your list oldMenu and then supply it to the constructor.
Revised code:
GridViewSelection(
menuList: oldMenu.length,
imageList: oldMenu.map((element) => element.image).toList(),
nameList: oldMenu.map((element) => element.name).toList(),
onTap: (){}),
Hope it helps!
Make sure that you're returning your widget inside itemBuilder of a list to be given the index to use it.

Overflow when using viewinsets in a modalButtomSheet

Problem:
I'm using MediaQuery and viewInsets to add Padding, when the user
triggers the keyboard in a modalBottomSheet.
It looks OK, but I get a message about overflow
When I draw down the modalBottomSheet manually, I can see the overflow happening behind the sheet.
Code first, then screenshots:
This is the GestureDetector opening the modal sheet:
GestureDetector(
onTap: () {
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(23.r),
),
),
isScrollControlled: true,
context: context,
builder: (bctx) => StatefulBuilder(builder:
(BuildContext context, StateSetter setModalState) {
return ModalAddFavorite();
}));
},
This is the Widegt that I use as modal sheeet:
class ModalAddFavorite extends StatefulWidget {
const ModalAddFavorite({Key? key}) : super(key: key);
#override
_ModalAddFavoriteState createState() => _ModalAddFavoriteState();
}
class _ModalAddFavoriteState extends State<ModalAddFavorite> {
#override
Widget build(BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setModalState) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom * 0.98.h),
//
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 20.h,
),
Container(
width: 80.w,
height: 6.w,
decoration: BoxDecoration(
color: Provider.of<CustomColors>(context, listen: false)
.customColorScheme['Grey 2'],
borderRadius: BorderRadius.circular(6.r),
),
),
SizedBox(
height: 25.h,
),
//
Text(
'ADD A FAVORITE',
style: Provider.of<CustomTextStyle>(context)
.customTextStyle('ModalHeader'),
),
SizedBox(
height: 25.5.h,
),
//
//
InputFieldAddFavorite(),
SizedBox(
height: 40.h,
)
],
),
),
);
});
}
}
Screenshots:
Modal Sheet open / keyboard inactive / no overflow
Modal sheet open / keyboard active / overflow warning in Flutter
Modal shett pulled back manually // overflow visible behind the sheet:
Try to add physics: NeverScrollableScrollPhysics() under your SingleChildScrollView().
Issue solved: Instead of wrapping the modal sheet in a SingleChildScrollView, I needed to wrap the Column that contains the page itself.

LateError was thrown building Obx(has builder, dirty, state: _ObxState#17527): LateInitializationError: Field 'products' has not been initialized

I am using GetX. I need to display the data from database one the application open. But i get the Exception.
The following LateError was thrown building Obx(has builder, dirty,
state: _ObxState#17527): LateInitializationError: Field 'products' has
not been initialized.
Although, I have initialize the late variable inside onInit.
The Controller Code Is:
class HomeController extends GetxController {
HomeController({required this.homeRepository});
final IHomeRepository homeRepository;
late Rx<Either<FireStoreServerFailures, List<Product>>> products; //=
#override
void onInit() async {
products.value= await fetchProductsFromDB();
super.onInit();
}
Future<Either<FireStoreServerFailures, List<Product>>> fetchProductsFromDB() async {
var _completer=Completer<Either<FireStoreServerFailures, List<Product>>>();
homeRepository.fetchProducts().listen((event) {
_completer.complete(event);
});
return await _completer.future;
}
}
Home Page Where I Am Used The Late Variable's Code Is:
Obx(
() => GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 2 / 2,
),
// TODO Deal with errors
itemCount: controller.products.value.getOrElse(() => []).length,
itemBuilder: (context, index) {
return controller.products.value.fold(
(l) => Container(
height: double.infinity,
width: double.infinity,
color: Colors.red,
child: Text("Error ${l.msg}"),
),
(r) => Card(
elevation: 2.0,
color: Colors.amber,
child: InkWell(
onTap: () async =>
await controller.goToMoreDetails(),
child: Stack(
fit: StackFit.expand,
clipBehavior: Clip.hardEdge,
children: [
Image.network(
controller.products.value.fold(
(l) => "",
(r) => r[index]
.pickedImages
.getOrCrash()[0]),
fit: BoxFit.fill,
height: 200,
width: 200,
),
OverflowBox(
minHeight: 30,
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.black.withOpacity(0.7),
height: 30,
width: double.infinity,
child: Center(
child: Text(
"${controller.products.value.fold((l) => "", (r) => r[index].price.getOrCrash())}",
style: const TextStyle(
color: Colors.white,
),
),
),
),
),
],
),
),
)) ;
}),
);
You declared late Rx<Either<FireStoreServerFailures, List<Product>>> products; but did not initialise products anywhere. But on your onInit method you tried to access .value on products which is not yet initialised. Setting products.value is not initialising products. Also, your Obx widget tries to access the products field which is not initialised by the time it tries to access.
What you should do is:
final products = Rxn<Either<FireStoreServerFailures, List<Product>>>();
And in your UI:
Obx(
() => controller.products.value == null? CircularProgressIndicator() : GridView.builder(......

Another exception was thrown: setState() or markNeedsBuild() called during build Error in flutter

Im new to flutter and working on an ecommerce flutter app. When im trying to navigate to search screen its giving some error. Please find the below codes for your reference and help to resolve.
Error :
The following assertion was thrown while dispatching notifications for SearchProvider:
setState() or markNeedsBuild() called during build.
This _InheritedProviderScope<SearchProvider?> widget cannot be marked as needing to build because
the framework is already in the process of building widgets. A widget can be marked as needing to
be built during the build phase only if one of its ancestors is currently building. This exception
is allowed because the framework builds parent widgets before children, which means a dirty
descendant will always be built. Otherwise, the framework might not visit this widget during this
build phase.
The widget on which setState() or markNeedsBuild() was called was:
_InheritedProviderScope<SearchProvider?>
The widget which was currently being built when the offending call was made was:
SearchScreen
Codes
Search Screen
class SearchScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
Provider.of<SearchProvider>(context, listen: false).cleanSearchProduct();
Provider.of<SearchProvider>(context, listen: false).initHistoryList();
return Scaffold(
backgroundColor: ColorResources.getIconBg(context),
resizeToAvoidBottomInset: true,
body: Column(
children: [
// for tool bar
SearchWidget(
hintText: getTranslated('SEARCH_HINT', context),
onSubmit: (String text) {
Provider.of<SearchProvider>(context, listen: false)
.searchProduct(text, context);
Provider.of<SearchProvider>(context, listen: false)
.saveSearchAddress(text);
},
onClearPressed: () {
Provider.of<SearchProvider>(context, listen: false)
.cleanSearchProduct();
},
),
Consumer<SearchProvider>(
builder: (context, searchProvider, child) {
return !searchProvider.isClear
? searchProvider.searchProductList != null
? searchProvider.searchProductList.length > 0
? Expanded(
child: SearchProductWidget(
products: searchProvider.searchProductList,
isViewScrollable: true))
: Expanded(
child:
NoInternetOrDataScreen(isNoInternet: false))
: Expanded(
child: ProductShimmer(
isHomePage: false,
isEnabled: Provider.of<SearchProvider>(context)
.searchProductList ==
null))
: Expanded(
flex: 4,
child: Container(
padding:
EdgeInsets.all(Dimensions.PADDING_SIZE_DEFAULT),
child: Stack(
clipBehavior: Clip.none,
children: [
Consumer<SearchProvider>(
builder: (context, searchProvider, child) =>
StaggeredGridView.countBuilder(
crossAxisCount: 3,
physics: NeverScrollableScrollPhysics(),
itemCount: searchProvider.historyList.length,
itemBuilder: (context, index) => Container(
alignment: Alignment.center,
child: InkWell(
onTap: () {
Provider.of<SearchProvider>(context,
listen: false)
.searchProduct(
searchProvider
.historyList[index],
context);
},
borderRadius: BorderRadius.circular(20),
child: Container(
padding: EdgeInsets.only(
left: 10,
right: 10,
top: 2,
bottom: 2),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(16),
color: ColorResources.getGrey(
context)),
width: double.infinity,
child: Center(
child: Text(
Provider.of<SearchProvider>(context,
listen: false)
.historyList[index] ??
"",
style: titilliumItalic.copyWith(
fontSize:
Dimensions.FONT_SIZE_SMALL),
),
),
),
)),
staggeredTileBuilder: (int index) =>
new StaggeredTile.fit(1),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
),
),
Positioned(
top: -5,
left: 0,
right: 0,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(getTranslated('SEARCH_HISTORY', context),
style: robotoBold),
InkWell(
borderRadius: BorderRadius.circular(10),
onTap: () {
Provider.of<SearchProvider>(context,
listen: false)
.clearSearchAddress();
},
child: Container(
padding: EdgeInsets.all(5),
child: Text(
getTranslated('REMOVE', context),
style: titilliumRegular.copyWith(
fontSize:
Dimensions.FONT_SIZE_SMALL,
color: Theme.of(context)
.primaryColor),
)))
],
),
),
],
),
),
);
},
),
],
),
);
}
}
Providers
void initHistoryList() {
_historyList = [];
_historyList.addAll(searchRepo.getSearchAddress());
notifyListeners();
}
void cleanSearchProduct() {
_searchProductList = [];
_isClear = true;
_searchText = '';
notifyListeners();
}
Try to use initial function calling in initState instead of build function
#override
void initState() {
WidgetsBinding.instance!.addPostFrameCallback((_) {
Provider.of<SearchProvider>(context, listen: false).cleanSearchProduct();
Provider.of<SearchProvider>(context, listen: false).initHistoryList();
});
super.initState();
}

Page value is only available after content dimensions are established

import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
class Slideshow extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: CarouselSlider(
options: CarouselOptions(
autoPlay: true,
enlargeCenterPage: true,
autoPlayCurve: Curves.easeInOut,
aspectRatio: 16 / 9,
viewportFraction: .75,
),
items: [
"https://firebasestorage.googleapis.com/v0/b/san-67ce2.appspot.com/o/clothes.jpeg?alt=media&token=d3be6bcb-4a40-4c78-a577-0b4f6a386536",
"https://firebasestorage.googleapis.com/v0/b/san-67ce2.appspot.com/o/clothes.jpeg?alt=media&token=d3be6bcb-4a40-4c78-a577-0b4f6a386536",
"https://firebasestorage.googleapis.com/v0/b/san-67ce2.appspot.com/o/clothes.jpeg?alt=media&token=d3be6bcb-4a40-4c78-a577-0b4f6a386536",
"https://firebasestorage.googleapis.com/v0/b/san-67ce2.appspot.com/o/clothes.jpeg?alt=media&token=d3be6bcb-4a40-4c78-a577-0b4f6a386536",
"https://firebasestorage.googleapis.com/v0/b/san-67ce2.appspot.com/o/clothes.jpeg?alt=media&token=d3be6bcb-4a40-4c78-a577-0b4f6a386536",
].map((i) {
return Builder(
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.black)),
child: Image.network(
i,
fit: BoxFit.fill,
alignment: Alignment.center,
)),
);
},
);
}).toList(),
),
);
}
}
I'm writing flutter code by using carousel slider package (package creates beautiful slideshow), this exception is being thrown every time I run the code, I couldn't understand why.
_AssertionError ('package:flutter/src/widgets/page_view.dart': Failed assertion: line 373 pos 7: 'pixels == null || (minScrollExtent != null && maxScrollExtent != null)': Page value is only available after content dimensions are established.)
Creates a MaterialApp.
At least one of [home], [routes], [onGenerateRoute], or [builder] must be
non-null.
https://blog.csdn.net/u013491829/article/details/108921275