I tried using expanded widget and other ways to solve this but I really don't know how to solve this error.. Thank you very much for the help everyone 👍
This is the error i get :
Exception has occurred. FlutterError (Horizontal viewport was given unbounded width. Viewports expand in the scrolling direction to fill their container. In this case, a horizontal viewport was given an unlimited amount of horizontal space in which to expand. This situation typically happens when a scrollable widget is nested inside another scrollable widget. If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough horizontal space for the children. In this case, consider using a Row or Wrap instead. Otherwise, consider using a CustomScrollView to concatenate arbitrary slivers into a single scrollable.)
grid code:
GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 2,
padding: EdgeInsets.fromLTRB(0, 13, 0, 30),
// crossAxisSpacing: 10,
childAspectRatio: size.width / (size.height * 0.59),
children: List.generate(allProducts.length, (index) {
return ChangeNotifierProvider.value(
value: allProducts[index],
child: Container(child: const FeedsWidget()));
}),
),
Pageview.builder code:
PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: productModel.imageUrl!.length,
itemBuilder: (context, index) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: FancyShimmerImage(
height: size.width * 0.28,
width: size.width * 0.38,
imageUrl: productModel.imageUrl![index],
boxFit: BoxFit.fill,
),
);
}),
This is my full code:
class FeedsScreen extends StatefulWidget {
static const routeName = "/FeedsScreenState";
const FeedsScreen({Key? key}) : super(key: key);
@override
State<FeedsScreen> createState() => _FeedsScreenState();
}
class _FeedsScreenState extends State<FeedsScreen> {
final TextEditingController? _searchTextController = TextEditingController();
final FocusNode _searchTextFocusNode = FocusNode();
@override
void dispose() {
_searchTextController!.dispose();
_searchTextFocusNode.dispose();
super.dispose();
}
@override
void initState() {
final productsProvider =
Provider.of<ProductsProvider>(context, listen: false);
productsProvider.fetchProducts();
super.initState();
}
@override
Widget build(BuildContext context) {
final productsProvider = Provider.of<ProductsProvider>(context);
List<ProductModel> allProducts = productsProvider.getProducts;
final Color color = Utils(context).color;
Size size = Utils(context).getScreenSize;
return Scaffold(
appBar: AppBar(
leading: const BackWidget(),
elevation: 0,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
centerTitle: true,
title: vTextWidget(
text: 'All Products',
color: color,
textSize: 20.0,
isTitle: true,
fontWeight: FontWeight.bold,
),
),
body: SingleChildScrollView(
child: Column(children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
height: kBottomNavigationBarHeight,
child: TextField(
focusNode: _searchTextFocusNode,
controller: _searchTextController,
onChanged: (valuee) {
setState(() {});
},
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide:
const BorderSide(color: Colors.greenAccent, width: 1),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide:
const BorderSide(color: Colors.greenAccent, width: 1),
),
hintText: "What's in your mind",
prefixIcon: const Icon(Icons.search),
suffix: IconButton(
onPressed: () {
_searchTextController!.clear();
_searchTextFocusNode.unfocus();
},
icon: Icon(
Icons.close,
color: _searchTextFocusNode.hasFocus ? Colors.red : color,
),
),
),
),
),
),
GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 2,
padding: EdgeInsets.fromLTRB(0, 13, 0, 30),
// crossAxisSpacing: 10,
childAspectRatio: size.width / (size.height * 0.59),
children: List.generate(allProducts.length, (index) {
return ChangeNotifierProvider.value(
value: allProducts[index],
child: Container(child: const FeedsWidget()));
}),
),
]),
),
);
}
}
and the widget page full code:
class FeedsWidget extends StatefulWidget {
static const routeName = "/feedItemsSc";
const FeedsWidget({Key? key}) : super(key: key);
@override
State<FeedsWidget> createState() => _FeedsWidgetState();
}
class _FeedsWidgetState extends State<FeedsWidget> {
final _quantityTextController = TextEditingController();
@override
void initState() {
_quantityTextController.text = '1';
super.initState();
}
@override
void dispose() {
_quantityTextController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final themeState = Provider.of<DarkThemeProvider>(context);
final productModel = Provider.of<ProductModel>(context);
final cartProvider = Provider.of<CartProvider>(context);
final wishlistProvider = Provider.of<WishlistProvider>(context);
bool? _isInCart = cartProvider.getCartItems.containsKey(productModel.id);
bool? _isInWishlist =
wishlistProvider.getWishlistItems.containsKey(productModel.id);
bool _isDark = themeState.getDarkTheme;
final Color color = Utils(context).color;
Size size = Utils(context).getScreenSize;
return Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 8, 8),
child: Material(
borderRadius: BorderRadius.circular(12),
color: Theme.of(context).cardColor,
child: InkWell(
onTap: () {
Navigator.pushNamed(context, ProductDetails.routeName,
arguments: productModel.id);
//GlobalMethods.navigateTo(
// ctx: context, routeName: ProductDetails.routeName);
},
borderRadius: BorderRadius.circular(12),
child: Column(children: [
Flexible(
flex: 3,
child: SizedBox(
height: 300,
width: 400,
child: productModel.imageUrl == null
? Image(
height: size.width * 0.28,
width: size.width * 0.38,
fit: BoxFit.fill,
image:
AssetImage('lib/assets/images/error_image.png'),
)
: PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: productModel.imageUrl!.length,
itemBuilder: (context, index) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: FancyShimmerImage(
height: size.width * 0.28,
width: size.width * 0.38,
imageUrl: productModel.imageUrl![index],
boxFit: BoxFit.fill,
),
);
}),
)),
//SizedBox(
// height: 8,
// ),
// FancyShimmerImage(
//imageUrl: productModel.imageUrl,
// height: size.width * 0.28,
// width: size.width * 0.38,
// boxFit: BoxFit.fill,
//),
SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 3,
child: fTextWidget(
text: productModel.title,
maxLines: 1,
color: color,
textSize: 22,
isTitle: true,
),
),
Flexible(
flex: 1,
child: HeartBTN(
productId: productModel.id,
isInWishlist: _isInWishlist,
)),
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(6, 8, 8, 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 3,
child: priceWidget(
isDark: _isDark,
salePrice: productModel.discountPrice,
price: productModel.price,
textPrice: _quantityTextController.text,
isOneSale: productModel.isDiscounted ? true : false,
),
),
// const SizedBox(
// width: 10,
// ),
/* Flexible(
child: Row(
children: [
FittedBox(
child: fTextWidget(
text: 'Qty',
color: color,
textSize: 18,
isTitle: true,
),
),
const SizedBox(
width: 4,
),
Flexible(
flex: 2,
child: TextFormField(
controller: _quantityTextController,
key: const ValueKey('10'),
style: TextStyle(color: color, fontSize: 17),
keyboardType: TextInputType.number,
maxLines: 1,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide()),
),
textAlign: TextAlign.center,
cursorColor: Colors.green,
enabled: true,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp('[0-9.,]'),
),
],
onChanged: (value) {
setState(() {
if (value.isEmpty) {
_quantityTextController.text = '1';
} else {
// total = usedPrice *
// int.parse(_quantityTextController.text);
}
});
},
onSaved: (value) {},
),
),
],
),
),*/
],
),
),
const Spacer(),
SizedBox(
width: double.infinity,
child: TextButton(
onPressed: _isInCart
? null
: () {
final User? user = authInstance.currentUser;
if (user == null) {
GlobalMethods.errorDialog(
subtitle: 'Please Login',
vicon: Icon(Icons.error),
context: context);
return;
}
// if (_isInCart) {
// return;
// }
cartProvider.addProductsToCart(
productId: productModel.id,
quantity: int.parse(_quantityTextController.text),
);
},
child: fTextWidget(
text: _isInCart ? 'Added' : 'Add to cart',
maxLines: 1,
color: color,
textSize: 20,
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Theme.of(context).cardColor),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12.0),
bottomRight: Radius.circular(12.0),
),
),
)),
),
),
]),
),
),
);
}
}
I have fixed the problem by adding a sized box and giving it height and width. Thus, the problem was fixed thanks for your help everyone.
Here is my updated Pageview.builder code:
child: SizedBox(
height: 120,
width: 400,
child: productModel.imageUrl == null
? Image(
height: size.width * 0.28,
width: size.width * 0.38,
fit: BoxFit.fill,
image: AssetImage('lib/assets/images/error_image.png'),
)
: PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: productModel.imageUrl!.length,
itemBuilder: (context, index) {
return ClipRRect(
borderRadius: BorderRadius.circular(10),
child: FancyShimmerImage(
height: size.width * 0.28,
width: size.width * 0.38,
imageUrl: productModel.imageUrl![index],
boxFit: BoxFit.fill,
),
);
}),
),