How pass Data to next screen from listview like image in flutter - flutter

i need to pass string and image to next screen from list view and that string and image are in listview
how should i pass them in flutter.
i have items in categories.dart
import 'package:flutter/material.dart';## Heading ##
List categories = [
{
"name": "Indian",
"color1": Color.fromARGB(100, 0, 0, 0),
"color2": Color.fromARGB(100, 0, 0, 0),
"img": "assets/indian.jpg"},
{
"name": "Italian",
"color1": Color.fromARGB(100, 0, 0, 0),
"color2": Color.fromARGB(100, 0, 0, 0),
"img": "assets/food1.jpeg"
},
{
"name": "Chinese",
"color1": Color.fromARGB(100, 0, 0, 0),
"color2": Color.fromARGB(100, 0, 0, 0),
"img": "assets/food2.jpeg"
},
{
"name": "Nigerian",
"color1": Color.fromARGB(100, 0, 0, 0),
"color2": Color.fromARGB(100, 0, 0, 0),
"img": "assets/food3.jpeg"
},
{
"name": "Spanish",
"color1": Color.fromARGB(100, 0, 0, 0),
"color2": Color.fromARGB(100, 0, 0, 0),
"img": "assets/food4.jpeg"
},
{
"name": "Mexican",
"color1": Color.fromARGB(100, 0, 0, 0),
"color2": Color.fromARGB(100, 0, 0, 0),
"img": "assets/food5.jpeg"
},
];
And my listview On first screen is on home.dart
Container(
height: MediaQuery.of(context).size.height/6,
child: ListView.builder(
primary: false,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: categories == null ? 0:categories.length,
itemBuilder: (BuildContext context, int index) {
Map cat = categories[index];
return
new InkWell(
onTap:() {
Navigator.of(context)
.push(MaterialPageRoute<Null>(builder: (BuildContext context) {
print(cat);
return new Manu_screen();
}));
},
child: Padding(
padding: EdgeInsets.only(right: 10.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Stack(
children: <Widget>[
Image.asset(
cat["img"],
height: MediaQuery.of(context).size.height/6,
width: MediaQuery.of(context).size.height/6,
fit: BoxFit.cover,
),
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
// Add one stop for each color. Stops should increase from 0 to 1
stops: [0.2, 0.7],
colors: [
cat['color1'],
cat['color2'],
],
// stops: [0.0, 0.1],
),
),
height: MediaQuery.of(context).size.height/6,
width: MediaQuery.of(context).size.height/6,
),
Center(
child: Container(
height: MediaQuery.of(context).size.height/6,
width: MediaQuery.of(context).size.height/6,
padding: EdgeInsets.all(1),
constraints: BoxConstraints(
minWidth: 20,
minHeight: 20,
),
child: Center(
child: Text(
cat["name"],
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
),
),
],
),
),
)
);
},
),
),
i need to get the data in categories to my secound screen how do i get it

You can pass an argument to your second screen:
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
print(cat);
return new Manu_screen(cat);
}
)
);
// Snippet from #Can Taşpınar
class Manu_screen extends StatelessWidget {
final Map cat;
Manu_screen({Key key, this.cat}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Text(cat["name"]),
);
}
}

As #Martyns said and Manu_screen can be like this:
class Manu_screen extends StatelessWidget {
final Map cat;
Manu_screen({Key key, this.cat}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Text(cat["name"]),
);
}
}

Related

flutter layout, Listview builder The relevant error-causing widget was: ListView

my code
in listview, alredy add shrinkWrap: true,
The following assertion was thrown during performLayout():
Assertion failed:
constraints.hasBoundedWidth
is not true
The relevant error-causing widget was:
ListView
When the exception was thrown, this was the stack:
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isLoading = true;
#override
void didChangeDependencies() {
// ignore: todo
// TODO: implement didChangeDependencies
super.didChangeDependencies();
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
Provider.of<HomeViewModel>(context, listen: false).getWisatas();
setState(() {
_isLoading = false;
});
});
}
#override
Widget build(BuildContext context) {
final modelView = Provider.of<HomeViewModel>(context, listen: true);
return Scaffold(
backgroundColor: cPrimary1,
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SafeArea(
top: true,
bottom: true,
child: Column(
children: <Widget>[
Expanded(
flex: 2,
child: Stack(
children: [
Container(
height: 220,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 5, color: CSeccond)),
image: DecorationImage(
image: AssetImage("assets/tugumangga.jpeg"),
fit: BoxFit.fill,
alignment: Alignment.bottomCenter),
),
),
Positioned(
top: 30,
left: 20,
child: RichText(
text: TextSpan(
text: "Selamat\nDatang",
style: TextStyle(
fontSize: 36,
color: Colors.white,
),
),
),
),
],
),
),
Expanded(
flex: 5,
child: Padding(
padding: EdgeInsets.only(right: 20, left: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Wisata Alam',
style: TextStyle(
fontSize: 18,
color: Colors.white,
),
),
SizedBox(
height: 8,
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListView.builder(
itemCount: modelView.wisatalist.length,
physics: BouncingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return GestureDetector(
child: BoxWisata(
h: 100,
w: 100,
fs: 13,
title: 'wisata',
img: 'assets/tugumangga.jpeg',
),
onTap: () => {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
// DetailScreen(
// nama: modelView
// .wisatalist[index]
// .nama,
// img: [],
// ),
// ))
});
}),
// BoxWisata(
// h: 100,
// w: 100,
// fs: 13,
// title: 'wisata',
// img: 'assets/tugumangga.jpeg',
// ),
// BoxWisata(
// h: 100,
// w: 100,
// fs: 13,
// title: 'wisata',
// img: 'assets/tugumangga.jpeg'),
// BoxWisata(
// h: 100,
// w: 100,
// fs: 13,
// title: 'wisata',
// img: 'assets/tugumangga.jpeg'),
// BoxWisata(
// h: 100,
// w: 100,
// fs: 13,
// title: 'wisata',
// img: 'assets/tugumangga.jpeg'),
// BoxWisata(
// h: 100,
// w: 100,
// fs: 13,
// title: 'wisata',
// img: 'assets/tugumangga.jpeg'),
],
),
),
],
),
)),
],
),
),
);
}
}
my widget box
import 'package:flutter/material.dart';
class BoxWisata extends StatelessWidget {
final String title;
final String img;
final double h;
final double w;
final double fs;
BoxWisata({
Key? key,
required this.title,
required this.img,
required this.h,
required this.w,
required this.fs,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
width: w,
height: h,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(25),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.6),
offset: const Offset(
0.0,
10.0,
),
blurRadius: 10.0,
spreadRadius: -6.0,
),
],
image: DecorationImage(
image: AssetImage(img),
fit: BoxFit.cover,
),
),
child: Stack(children: [
Align(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Text(
title,
style: TextStyle(
fontSize: fs,
color: Colors.black,
fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
maxLines: 2,
textAlign: TextAlign.center,
),
),
alignment: Alignment.center,
)
]),
);
}
}
errorcode
he following assertion was thrown during performLayout():
Assertion failed:
constraints.hasBoundedWidth
is not true
The relevant error-causing widget was:
ListView
When the exception was thrown, this was the stack:
This might help
Column(
children: <Widget>[
Stack(
children: [
Container(
height: 220,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(width: 5, color: Colors.green),
),
image: DecorationImage(
image: NetworkImage("https://picsum.photos/200/300"),
fit: BoxFit.fill,
alignment: Alignment.bottomCenter,
),
),
),
Positioned(
top: 30,
left: 20,
child: RichText(
text: const TextSpan(
text: "Selamat\nDatang",
style: TextStyle(
fontSize: 36,
color: Colors.white,
),
),
),
),
],
),
const Text(
'Wisata Alam',
style: TextStyle(
fontSize: 18,
color: Colors.white,
),
),
const SizedBox(height: 8),
Expanded(
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 100,
physics: const BouncingScrollPhysics(),
itemBuilder: (context, index) {
return GestureDetector(
child: Container(
padding: const EdgeInsets.all(12),
alignment: Alignment.center,
color: Colors
.primaries[Random().nextInt(Colors.primaries.length)],
child: Text('wisata $index'),
),
onTap: () => {},
);
},
),
),
],
);

Flutter ListView builder not updating with fresh data

I'm running a search filter function which retrieves players from a Floor DB. The functionality works fine and I can see through logs that the new player are returned, however my UI won't update which seems to be from the new list i assign not triggering a re-render.
Can anyone see what's wrong with my code?
import 'package:flutter/material.dart';
import '../database/LocalDatabase.dart';
import '../model/Player.dart';
class Pitch extends StatefulWidget {
const Pitch({super.key});
#override
_Pitch createState() => _Pitch();
}
class _Pitch extends State<Pitch> {
List<Player> playersList = <Player>[];
Offset positionOne = const Offset(100, 100);
Offset positionTwo = const Offset(200, 100);
#override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints.expand(),
color: Colors.white,
child: Stack(
alignment: Alignment.center,
children: [
Image.asset("assets/images/pitch.png"),
Positioned(
left: positionOne.dx,
top: positionOne.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
),
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
onDragEnd: (details) {
setState(() {
positionOne = details.offset;
});
},
),
),
Positioned(
left: positionTwo.dx,
top: positionTwo.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
),
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
onDragEnd: (details) {
setState(() {
positionTwo = details.offset;
});
},
),
)
],
),
);
}
#override
void initState() {
super.initState();
// getPlayers().then((value) {
// debugPrint("playerfromdb: ${value[0].name}");
// });
}
Future<List<Player>> getPlayers() async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final playerDao = database.playerDao;
final players = playerDao.getAllPlayers();
return players;
}
Widget playerImage(String imageUrl) {
return GestureDetector(
onTap: () => showDialog<void>(
context: context,
builder: (BuildContext context) => Dialog(
backgroundColor: Colors.white,
child: SizedBox(
height: 300,
width: 300,
child: Column(
children: [
const SizedBox(height: 24),
Container(
margin: const EdgeInsets.only(left: 16),
height: 48,
child: TextField(
decoration: const InputDecoration.collapsed(
hintText: 'Enter player name',
focusColor: Colors.transparent),
onChanged: (value) {
searchPlayers(value);
},
)),
const SizedBox(height: 24),
SizedBox(
height: 200,
child: ListView.builder(
itemCount: playersList.length,
itemBuilder: (context, index) {
return playerItem(playersList.elementAt(index));
}),
),
],
)))),
child: SizedBox(
width: 48,
height: 48,
child: Image.network(imageUrl),
));
}
Widget playerItem(Player? player) {
return Container(
height: 48,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [BoxShadow(blurRadius: 8)]),
child: Row(
children: [
SizedBox(
height: 36,
width: 36,
child: Image.network(player?.playerImageUrl ?? "")),
const SizedBox(width: 8),
Text(player?.name ?? "")
],
),
);
}
Future<void> searchPlayers(String query) async {
final database = await $FloorLocalDatabase
.databaseBuilder('local_database.db')
.build();
final playerDao = database.playerDao;
// await List<Player> filteredPlayers =
playerDao.searchPlayers(query).then((value) {
setState(() => playersList = value);
debugPrint(value[0].name);
});
}
}
Because your put ListView.builder in Dialog it will create a new stack and a new stack can't rerender from another stack
You can change your code with create a new stateful widget for dialogs
import 'package:flutter/material.dart';
import '../database/LocalDatabase.dart';
import '../model/Player.dart';
class Pitch extends StatefulWidget {
const Pitch({super.key});
#override
_Pitch createState() => _Pitch();
}
class _Pitch extends State<Pitch> {
Offset positionOne = const Offset(100, 100);
Offset positionTwo = const Offset(200, 100);
#override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints.expand(),
color: Colors.white,
child: Stack(
alignment: Alignment.center,
children: [
Image.asset("assets/images/pitch.png"),
Positioned(
left: positionOne.dx,
top: positionOne.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
),
child: playerImage(
"https://cdn.sofifa.net/players/158/023/22_120.png"),
onDragEnd: (details) {
setState(() {
positionOne = details.offset;
});
},
),
),
Positioned(
left: positionTwo.dx,
top: positionTwo.dy,
child: Draggable(
feedback: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
childWhenDragging: Opacity(
opacity: 0,
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
),
child: playerImage(
"https://cdn.sofifa.com/players/notfound_0_120.png"),
onDragEnd: (details) {
setState(() {
positionTwo = details.offset;
});
},
),
)
],
),
);
}
Widget playerImage(String imageUrl) {
return GestureDetector(
onTap: () => showDialog<void>(
context: context,
builder: (BuildContext context) => Dialog(
backgroundColor: Colors.white,
child: const PlayersDialog(),
),
),
child: SizedBox(
width: 48,
height: 48,
child: Image.network(imageUrl),
),
);
}
}
class PlayersDialog extends StatefulWidget {
const PlayersDialog({super.key});
#override
_PlayersDialog createState() => _PlayersDialog();
}
class _PlayersDialog extends State<PlayersDialog> {
List<Player> playersList = <Player>[];
Future<void> searchPlayers(String query) async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final playerDao = database.playerDao;
// await List<Player> filteredPlayers =
playerDao.searchPlayers(query).then((value) {
setState(() => playersList = value);
debugPrint(value[0].name);
});
}
#override
Widget build(BuildContext context) {
return SizedBox(
height: 300,
width: 300,
child: Column(
children: [
const SizedBox(height: 24),
Container(
margin: const EdgeInsets.only(left: 16),
height: 48,
child: TextField(
decoration: const InputDecoration.collapsed(
hintText: 'Enter player name',
focusColor: Colors.transparent),
onChanged: (value) {
searchPlayers(value);
},
)),
const SizedBox(height: 24),
SizedBox(
height: 200,
child: ListView.builder(
itemCount: playersList.length,
itemBuilder: (context, index) {
return playerItem(playersList.elementAt(index));
},
),
),
],
),
);
}
Widget playerItem(Player? player) {
return Container(
height: 48,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: const [BoxShadow(blurRadius: 8)]),
child: Row(
children: [
SizedBox(
height: 36,
width: 36,
child: Image.network(player?.playerImageUrl ?? "")),
const SizedBox(width: 8),
Text(player?.name ?? "")
],
),
);
}
#override
void initState() {
super.initState();
// getPlayers().then((value) {
// debugPrint("playerfromdb: ${value[0].name}");
// });
}
Future<List<Player>> getPlayers() async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final playerDao = database.playerDao;
final players = playerDao.getAllPlayers();
return players;
}
}

Unable to add elements to a List in Flutter

Issue:
I am trying to add items to wishlist and cart on pressing relevant icons of an instrument item card. However, when I tap on them, neither are they getting added to the global lists of wishList and cartList, nor are the wishList and cart icons changing colors to red and blue respectively.
Below are my codes for the relevant .dart files.
home_welcome_screen.dart - The screen which hosts the instrument item cards in a horizontal ListView:
import 'package:flutter/material.dart';
import 'package:musicart/screens/instrument_detail.dart';
import 'package:musicart/screens/wishlist_screen.dart';
import 'package:musicart/widgets/animated_bottom_bar.dart';
import 'package:musicart/widgets/brand_logo_card.dart';
import 'package:musicart/widgets/instrument_card.dart';
import 'package:musicart/widgets/search_widget.dart';
import 'package:musicart/widgets/text_label.dart';
import '../global_variables/global_variables.dart';
import 'package:carousel_slider/carousel_slider.dart';
class HomeWelcomeScreen extends StatefulWidget {
const HomeWelcomeScreen({Key? key}) : super(key: key);
#override
State<HomeWelcomeScreen> createState() => _HomeWelcomeScreenState();
}
class _HomeWelcomeScreenState extends State<HomeWelcomeScreen> {
final TextEditingController _searchBoxController = TextEditingController();
final String _hintText = "Search instruments...";
int _currentIndex = 0;
int _currentCarouselIndex = 0;
#override
Widget build(BuildContext context) {
double? screenWidth = MediaQuery.of(context).size.width;
double? screenHeight = MediaQuery.of(context).size.height;
List<Widget> indicators(imagesLength, currentIndex) {
return List<Widget>.generate(imagesLength, (index) {
return Container(
margin: EdgeInsets.symmetric(
vertical: screenHeight * 0.01,
horizontal: 2,
),
width: currentIndex == index ? 15 : 10,
height: 3,
decoration: BoxDecoration(
color: currentIndex == index ? Colors.black87 : Colors.grey,
borderRadius: const BorderRadius.all(
Radius.circular(2),
),
),
);
});
}
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: screenHeight * 0.02),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(
left: screenWidth * 0.025, right: screenWidth * 0.19),
child: Image(
image: const AssetImage("../assets/images/logo.png"),
height: 40,
width: screenWidth * 0.25,
),
),
Padding(
padding: EdgeInsets.only(right: screenWidth * 0.025),
child: SearchWidget(
width: screenWidth * 0.3,
onChanged: (p0) {},
searchController: _searchBoxController,
onTap: () {},
hintText: _hintText,
),
),
Padding(
padding: EdgeInsets.only(right: screenWidth * 0.025),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
WishListScreen(mywishList: wishList[0])));
},
child: const Icon(
Icons.favorite_outline_rounded,
color: Colors.black87,
size: 40,
),
),
),
Padding(
padding: EdgeInsets.only(right: screenWidth * 0.025),
child: InkWell(
onTap: () {},
child: const Icon(
Icons.shopping_cart_outlined,
color: Colors.black87,
size: 40,
),
),
),
],
),
Padding(
padding: EdgeInsets.only(top: screenHeight * 0.015),
),
SizedBox(
width: screenWidth,
height: screenHeight,
child: Column(
children: [
Expanded(
child: ListView(
children: [
// Padding(
// padding: EdgeInsets.only(top: screenHeight * 0.01)),
CarouselSlider(
items: carouselImageList.map<Widget>((i) {
return Builder(
builder: (BuildContext context) {
return Container(
width: screenWidth * 0.95,
decoration: BoxDecoration(
image:
DecorationImage(image: NetworkImage(i)),
),
);
},
);
}).toList(),
options: CarouselOptions(
height: screenHeight * 0.25,
aspectRatio: 16 / 9,
autoPlay: true,
autoPlayInterval: const Duration(seconds: 5),
initialPage: 0,
viewportFraction: 1,
onPageChanged: (index, timed) {
setState(() {
_currentCarouselIndex = index;
});
}),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: indicators(
carouselImageList.length, _currentCarouselIndex),
),
Padding(
padding: EdgeInsets.only(
left: screenWidth * 0.025,
top: screenHeight * 0.005,
),
child: TextLabel(
width: screenWidth * 0.15,
labelText: "Top Brands",
),
),
Padding(
padding: EdgeInsets.only(
left: screenWidth * 0.025,
top: screenWidth * 0.025),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: screenWidth * 0.025),
child: SizedBox(
height: screenHeight * 0.1,
child: Row(
children: [
Expanded(
child: ListView.builder(
itemCount: brandLogos.length,
scrollDirection: Axis.horizontal,
//shrinkWrap: true,
physics:
const AlwaysScrollableScrollPhysics(),
itemBuilder:
(BuildContext context, int index) {
return BrandLogoCard(
width: screenWidth * 0.33,
height: screenHeight * 0.18,
brandImageUrl: brandLogos[index]
["img-url"],
paddingRight: screenWidth * 0.015);
},
),
),
],
),
),
),
Padding(
padding: EdgeInsets.only(
left: screenWidth * 0.025,
top: screenWidth * 0.025),
),
Padding(
padding: EdgeInsets.only(
left: screenWidth * 0.025,
),
child: TextLabel(
width: screenWidth * 0.21,
labelText: "Trending Guitars",
),
),
Padding(
padding: EdgeInsets.only(
left: screenWidth * 0.025,
top: screenWidth * 0.025),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: screenWidth * 0.025),
child: SizedBox(
height: screenHeight * 0.28,
child: Row(
children: [
Expanded(
child: ListView.builder(
itemCount: instruments.length,
scrollDirection: Axis.horizontal,
//shrinkWrap: true,
physics:
const AlwaysScrollableScrollPhysics(),
itemBuilder:
(BuildContext context, int index) {
return InstrumentCard(
width: screenWidth * 0.4,
height: screenHeight * 0.37,
instrumentImageUrl: instruments[index]
["img-url"],
instrumentName: instruments[index]
["name"],
instrumentMrp:
"₹${instruments[index]["mrp"].toString()}",
instrumentPrice:
"₹${instruments[index]["price"].toString()}",
paddingRight: screenHeight * 0.015,
innerHorizontalSymmetricPadding:
screenWidth * 0.025,
innerVerticalSymmetricPadding:
screenHeight * 0.005,
instrumentDiscount:
"${(((1 - (instruments[index]["price"] / instruments[index]["mrp"])) * 100).round()).toString()}% off",
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
InstrumentDetail(
instrument: instruments[
index])));
},
onWishTap: () {
if (wishList
.contains(instruments[index])) {
setState(() {
wishList.remove(instruments[index]);
});
} else {
setState(() {
wishList.add(instruments[index]);
});
}
},
onCartTap: () {
if (cartList
.contains(instruments[index])) {
setState(() {
cartList.remove(instruments[index]);
});
} else {
setState(() {
cartList.add(instruments[index]);
});
}
},
isWishlisted: (wishList
.contains(instruments[index]))
? true
: false,
isCarted: (cartList
.contains(instruments[index]))
? true
: false,
);
},
),
),
],
),
),
),
Padding(
padding: EdgeInsets.only(
left: screenWidth * 0.025,
top: screenWidth * 0.025),
),
],
),
),
],
),
),
],
),
}
}
instrument_card.dart - The widget for the instrument item displayed on the HomeWelcomeScreen
import 'package:flutter/material.dart';
import 'package:musicart/global_variables/global_variables.dart';
class InstrumentCard extends StatefulWidget {
const InstrumentCard({
Key? key,
required this.width,
required this.height,
required this.instrumentImageUrl,
required this.instrumentName,
required this.instrumentMrp,
required this.instrumentPrice,
required this.paddingRight,
required this.innerHorizontalSymmetricPadding,
required this.innerVerticalSymmetricPadding,
required this.instrumentDiscount,
required this.onTap,
required this.onWishTap,
required this.onCartTap,
required this.isWishlisted,
required this.isCarted,
}) : super(key: key);
final double width;
final double height;
final String instrumentImageUrl;
final String instrumentName;
final String instrumentMrp;
final String instrumentPrice;
final double paddingRight;
final double innerHorizontalSymmetricPadding;
final double innerVerticalSymmetricPadding;
final String instrumentDiscount;
final VoidCallback onTap;
final VoidCallback onWishTap;
final VoidCallback onCartTap;
final bool isWishlisted;
final bool isCarted;
#override
State<InstrumentCard> createState() => _InstrumentCardState();
}
class _InstrumentCardState extends State<InstrumentCard> {
bool isWishlisted = false;
bool isCarted = false;
#override
void initState() {
super.initState();
isWishlisted = widget.isWishlisted;
isCarted = widget.isCarted;
}
#override
Widget build(BuildContext context) {
return InkWell(
onTap: widget.onTap,
child: Padding(
padding: EdgeInsets.only(right: widget.paddingRight),
child: Stack(
children: [
Container(
width: widget.width,
height: widget.height,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey,
width: 0.5,
),
borderRadius: const BorderRadius.all(
Radius.circular(10),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: widget.width,
height: widget.height * 0.5,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(widget.instrumentImageUrl),
fit: BoxFit.fill,
),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
border: Border.all(color: Colors.grey, width: 0.015),
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: widget.innerHorizontalSymmetricPadding,
vertical: widget.innerVerticalSymmetricPadding,
),
child: Text(
widget.instrumentName,
style: globalTextStyle.copyWith(
color: Colors.black87,
fontSize: 14,
fontWeight: FontWeight.bold),
),
),
Row(
children: [
Padding(
padding: EdgeInsets.only(left: widget.width * 0.07)),
Text(
widget.instrumentPrice,
style: globalTextStyle.copyWith(
color: Colors.green.shade900,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
Padding(
padding: EdgeInsets.only(left: widget.width * 0.07)),
Text(
widget.instrumentMrp,
style: globalTextStyle.copyWith(
color: Colors.grey,
fontSize: 12,
decoration: TextDecoration.lineThrough,
),
),
],
),
Padding(padding: EdgeInsets.only(top: widget.height * 0.025)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: widget.width / 2,
decoration: const BoxDecoration(
border: Border(
top: BorderSide(color: Colors.grey, width: 0.2),
right: BorderSide(color: Colors.grey, width: 0.2),
),
),
child: InkWell(
onTap: () {
// setState(() {
// isWishlisted = !isWishlisted;
// });
widget.onWishTap;
},
child: Padding(
padding: EdgeInsets.symmetric(
vertical: widget.height * 0.0125),
child: (isWishlisted)
? Icon(
Icons.favorite_rounded,
color: Colors.red.shade900,
)
: const Icon(
Icons.favorite_border_rounded,
color: Colors.black87,
),
),
),
),
Container(
width: widget.width / 2,
decoration: const BoxDecoration(
border: Border(
top: BorderSide(color: Colors.grey, width: 0.2),
right: BorderSide(color: Colors.grey, width: 0.2),
),
),
child: InkWell(
onTap: () {
// setState(() {
// isCarted = !isCarted;
// });
widget.onCartTap;
},
child: Padding(
padding: EdgeInsets.symmetric(
vertical: widget.height * 0.0125),
child: (isCarted)
? Icon(Icons.shopping_cart_rounded,
color: Colors.blue.shade900)
: const Icon(
Icons.shopping_cart_outlined,
color: Colors.black87,
),
),
),
),
],
),
],
),
),
Positioned(
right: 0,
top: widget.height * 0.075,
child: Container(
width: widget.width * 0.25,
height: widget.height * 0.07,
decoration: BoxDecoration(
color: Colors.green.shade900,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(5),
bottomLeft: Radius.circular(5),
),
),
child: Padding(
padding: EdgeInsets.only(
left: widget.width * 0.04,
top: widget.height * 0.016,
),
child: Text(
widget.instrumentDiscount,
style: globalTextStyle.copyWith(
color: Colors.white70,
fontSize: 10,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
),
);
}
}
global_variables.dart - a Dart file that contains the list of map elements of instrument items and also has empty lists declared for wishList and cartList where I intend to add/remove instrument items based on tapping the instrument item cards on the HomeWelcomeScreen
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../widgets/animated_bottom_bar.dart';
TextStyle globalTextStyle = GoogleFonts.lato();
const _inactiveColor = Colors.grey;
const _activeColor = Colors.white70;
List<Map<String, dynamic>> brandLogos = [
{
"brand": "fender",
"img-url":
"https://png.pngitem.com/pimgs/s/159-1597814_fender-guitar-hd-png-download.png",
},
{
"brand": "yamaha",
"img-url":
"https://www.motoroids.com/wp-content/uploads/2011/03/Yamaha-logo.jpg",
},
{
"brand": "ibanez",
"img-url":
"https://s0.bukalapak.com/img/57118379431/large/IBANEZ_GUITAR_sticker_logo_ibanez_gitar_stiker_murah_8cm.jpg",
},
{
"brand": "gibson",
"img-url":
"https://i.etsystatic.com/34531699/r/il/cd1ba7/3800299077/il_340x270.3800299077_1e91.jpg",
},
{
"brand": "tama",
"img-url": "https://www.vector-logo.net/logo_preview/eps/t/Tama.png",
},
];
List<Map<String, dynamic>> instruments = [
{
"instrument": "Guitar",
"name": "Fender Stratocaster",
"brand": "Fender",
"mrp": 62000,
"price": 58900,
"rating": 4.7,
"reviews": 11,
"img-url":
"https://cdn.shopify.com/s/files/1/0657/6821/products/FEN-0144522500_grande.jpg?v=1639964521",
},
{
"instrument": "Guitar",
"name": "Squier Bullet Strat",
"brand": "Fender",
"mrp": 17280,
"price": 11900,
"rating": 4.5,
"reviews": 188,
"img-url":
"https://cdn.shopify.com/s/files/1/0657/6821/products/SQUIERBULLETSTRAT_0934fec6-212d-4e8e-84d2-27c52f31c427_large.jpg?v=1653118647",
},
{
"instrument": "Guitar",
"name": "Les Paul Studio LT",
"brand": "Epiphone",
"mrp": 29999,
"price": 24604,
"rating": 4.4,
"reviews": 11,
"img-url":
"https://cdn.shopify.com/s/files/1/0657/6821/products/SQUIERBULLETSTRAT_0934fec6-212d-4e8e-84d2-27c52f31c427_large.jpg?v=1653118647",
},
{
"instrument": "Guitar",
"name": "KX 100 HT",
"brand": "Cort",
"mrp": 21542,
"price": 17176,
"rating": 5.0,
"reviews": 2,
"img-url":
"https://cdn.shopify.com/s/files/1/0657/6821/products/io_large.jpg?v=1640775516",
},
{
"instrument": "Guitar",
"name": "Jet-1",
"brand": "Aria",
"mrp": 15174,
"price": 14416,
"rating": 4.0,
"reviews": 1,
"img-url":
"https://cdn.shopify.com/s/files/1/0657/6821/products/ARI-JET1BK_large.jpg?v=1639700162",
},
];
List<Map<String, dynamic>> wishList = [];
List<Map<String, dynamic>> cartList = [];
My logic so far: I have tried calling VoidCallBack functions which when the relevant UI is tapped on will set the state in which the specific instrument card item will be added/removed from the wishlist or cart lists. Also, I have got two boolean propetries of the InstrumentCard, one each for isWishlisted and isCarted whose values will be toggled betwen true and false based on whether the specific instrument item is present or absent in the wishlist or cart. Their boolean values will be used for rendering the relvant icons (added - red/blue or empty - outlined) for the wishlist and cart.
Request: What is wrong with my logic and how will I add/remove items to the wishlist and cart?
Screenshot for reference:
To call a method inside tap you need to use (). Do it like
onTap: () {
setState(() {
isCarted = !isCarted;
});
widget.onCartTap(); //this

how to make this table scrollable to bottom

i am beginner in flutter , i wrote a code with a leagueboard table from api , after i executed i found that my table is not scrolling , the scroll appears only on the top but no scrolling to bottom
here what i have tried:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:http/http.dart' as http;
class LeagueBoard extends StatefulWidget {
#override
_LeagueBoardState createState() => _LeagueBoardState();
}
class _LeagueBoardState extends State<LeagueBoard> {
List<Club> clubs = [];
getTable() async {
http.Response response = await http.get(
'http://api.football-data.org/v2/competitions/PL/standings',
headers: {'X-Auth-Token': '86014f6025ae430dba078acc94bb2647'});
String body = response.body;
Map data = jsonDecode(body);
List table = data['standings'][0]['table'];
// for (var team in table) {
// clubs.add(Club(team['team']['crestUrl'].toString(), team['position'].toString(),team['points'].toString(),team['points'].toString(),team['playedGames'].toString(),team['won'].toString(),
// team['draw'].toString(),team['lost'].toString(),team['goalsFor'],team['goalsAgainst']));
// print(team);
// }
// for (var team in table) {
// clubs.add(Club(team['team']['crestUrl'].toString(), team['position'].toString(),team['points'].toString(),team['points'].toString(),team['playedGames'].toString(),team['won'].toString(),
// team['draw'].toString(),team['lost'].toString(),team['goalsFor'],team['goalsAgainst']));
// print(team);
// }
// for (var team in clubs) {
// debugPrint(team.toString());
// }
setState(() {
for (var team in table) {
clubs.add(Club(team['team']['name'],team['team']['crestUrl'], team['position'].toString(),team['points'].toString(),team['playedGames'].toString(),team['won'].toString(),
team['draw'].toString(),team['lost'].toString(),team['goalsFor'],team['goalsAgainst']));
print("hello");
}
});
}
// List<Club> clubs = [ Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),
// Club("Manchester City","https://upload.wikimedia.org/wikipedia/fr/thumb/b/ba/Logo_Manchester_City_2016.svg/1200px-Logo_Manchester_City_2016.svg.png","1","77","17","15","1","1",25,5),
// Club("Chelsea","https://upload.wikimedia.org/wikipedia/fr/thumb/5/51/Logo_Chelsea.svg/768px-Logo_Chelsea.svg.png","2","70","17","13","2","3",19,8),];
#override
void initState() {
super.initState();
getTable();
}
#override
Widget build(BuildContext context) {
return clubs == null
? Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Color(0xFFe70066),
),
),
),
)
: Scaffold(
appBar: AppBar(
title: Text("LeagueBoard"),
backgroundColor: Colors.blue[300],
elevation: 0.0,
),
body: SingleChildScrollView(
child: Column(
children: [
TopRow(),
ListView.builder(
shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
itemCount: clubs.length,
itemBuilder: (context, index) {
return TableRow(index: index, clubs:clubs);
},
),
],
),
),
);
}
}
class TopRow extends StatelessWidget {
const TopRow({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
TextStyle textStyle = TextStyle(fontSize: 11, fontWeight: FontWeight.bold);
TextStyle textStyle2 = TextStyle(fontSize: 13);
return Container(
child: Row(
children: [
Container(
alignment: Alignment.center,
width: 30,
height: 30,
child: Text('#'),
),
SizedBox(width: 20),
Container(alignment: Alignment.center, child: Text('Team')),
Spacer(),
Container(
width: 28,
child: Text('MP', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('W', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('D', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('L', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('GD', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text('Pts', style: textStyle),
),
SizedBox(
width: 5,
),
Container(
width: 5,
height: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.grey[800],
),
padding: EdgeInsets.fromLTRB(10, 5, 2, 5),
),
],
),
);
}
}
class TableRow extends StatelessWidget {
final int index;
final List<Club> clubs;
const TableRow({
this.index,
this.clubs,
Key key,
}) : super(key: key);
/////////////////////////////////////////////////////////////////////linkwell
////////////////////////////////////////////////////////////////////
#override
Widget build(BuildContext context) {
TextStyle textStyle = TextStyle(fontSize: 11, fontWeight: FontWeight.bold);
TextStyle textStyle2 = TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
return Container(
width: double.infinity,
height: 40,
decoration: BoxDecoration(
border: Border.all(color: Colors.black38, width: 0.2),
color: index == 0 ? Colors.yellow[100] : Colors.purpleAccent[20],
),
child: Row(
children: [
Container(//iinkwell
alignment: Alignment.center,
width: 30,
height: 40,
color: index < 2
? Colors.blue
: index == 2
? Colors.red[400]
: index > 11
? Colors.red[800]
: Colors.grey[700],
child: Text(
(index + 1).toString(),
style: TextStyle(color: Colors.white),
),
),
SizedBox(width: 20),
Row(children: [
SvgPicture.network(clubs[index].image,
width: 24.0, height: 24.0,
),
SizedBox(width: 5.0),
clubs[index].name.length > 11
? Text(clubs[index].name
.toString()
.substring(0, 11) +
'...')
: Text(clubs[index].name.toString(), style: textStyle2),
],),
Spacer(),
Container(
width: 28,
child: Text(clubs[index].matches, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].wins, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].draws, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].loss, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text((clubs[index].goals - clubs[index].goalsIn).toString(), style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 28,
child: Text(clubs[index].points, style: textStyle2),
),
SizedBox(
width: 5,
),
Container(
width: 5,
height: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.grey[600],
),
padding: EdgeInsets.fromLTRB(10, 5, 2, 5),
),
],
),
);
}
}
class Club {
String name;
String image;
String rank;
String points;
String matches;
String wins;
String loss;
String draws;
int goals;
int goalsIn;
Club(this.name,this.image,this.rank,this.points, this.matches,this.wins,this.loss,this.draws,this.goals,this.goalsIn);
}
I am trying to make my table scrolling because i can not see all of the teams that came from becand due to non scrolling reasons
You are using ListView inside SingleChildScrollView. So set that ListView as non-primary.
primary: false
Change at this point in your code
ListView.builder(
shrinkWrap: true,
primary: false,
// physics: NeverScrollableScrollPhysics(),
itemCount: clubs.length,
itemBuilder: (context, index) {
return TableRow(index: index, clubs:clubs);
},
),

ChangeNotifierProvider shows gray screen

I have the following code
class to hold my items as follows:
class ItemList extends ChangeNotifier {
List items = [
{
"id": "1",
"type": "men",
"liked" : true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price" : 1,
},
{
"id": "2",
"type": "men",
"liked" : true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price" : 2,
},
{
"id": "3",
"type": "men",
"liked" : true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price" : 3,
},
{
"id": "4",
"type": "men",
"liked" : true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price" : 4,
},
{
"id": "5",
"type": "men",
"liked" : true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price" : 5,
},
];
likeAndUnlike(id){
items.forEach((item) {
if(item['id'] == id){
item['liked'] = !item['liked'];
}
} ) ;
notifyListeners() ;
}
}
and a class to return the items from the ItemList class as follows:
class LikedProduct extends StatelessWidget {
final productDetails;
LikedProduct({this.productDetails});
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
print("insideLikedProject");
return Padding(
padding: EdgeInsets.only(bottom: 22),
child: GestureDetector(
onTap: () {
print("CLICKED!");
child: Container(
height: size.height * 0.15,
width: size.width * 0.9,
child: Row(
children: <Widget>[
Hero(
transitionOnUserGestures: true,
tag: productDetails['id'],
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.asset(
productDetails['img'],
width: size.width * 0.35,
height: size.height * 0.15,
fit: BoxFit.cover,
),
),
),
SizedBox(
width: 8,
),
SizedBox(
height: size.height * 0.13,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
productDetails['type'],
style: style.headerStyle3,
),
Text(
productDetails['price'].toString() + " OMR",
style: style.textTheme
.copyWith(color: Theme.of(context).primaryColor),
),
],
),
)
],
),
),
),
);
}
}
Then I call the LikedProduct class inside ChangeNotifierProvider as follows:
class OrdersUI extends StatefulWidget {
#override
_OrdersUIState createState() => _OrdersUIState();
}
class _OrdersUIState extends State<OrdersUI> {
final totalCost = 0;
final jeansPrice = 0;
final jeansCounter = 0;
final standardDeliveryCost = 5;
final expressDeliveryCost = 15;
void _changeTotalPrice() {
setState(() {});
}
final productDetails;
_OrdersUIState({this.productDetails});
#override
Widget build(BuildContext context) {
final data = MediaQuery.of(context);
final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: Align(
alignment: Alignment.center,
child: Text(
'Title',
style: TextStyle(color: Colors.black),
)),
actions: <Widget>[],
backgroundColor: Colors.white,
),
body: Container(
width: data.size.width,
//height: data.size.height * 0.05,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Container(
color: Color.fromARGB(255, 81, 202, 238),
height: data.size.height * 0.05,
width: data.size.width,
alignment: Alignment.topCenter,
child: Align(
alignment: Alignment.center,
child: Text(
'Total : ${totalCost.toString()} OMR',
))),
),
],
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
child: Column(
children: <Widget>[
ChangeNotifierProvider<ItemList>(
create: (context) => locator<ItemList>(),
child: Consumer<ItemList>(
builder: (context, model, child) {
print("Inside Builder"); // doesn't get executed
return Expanded(
child: ListView.builder(
physics: ScrollPhysics(
parent: BouncingScrollPhysics()),
shrinkWrap: true,
itemCount: model.items.length,
itemBuilder: (context, index) {
print('Inside Item Builder'); // doesn't get executed
return LikedProduct(
productDetails: model.items[index],
);
},
),
);
},
),
),
],
),
),
Row(
children: <Widget>[
Expanded(
child: Container(
//margin: const EdgeInsets.only(left: 50.0, right: 50.0),
child: Divider(
height: 1,
thickness: 1,
color: Colors.grey.shade700,
),
),
)
],
),
],
)
)
);
}
}
And the locator file used inside ChangeNotifierProvider is to register the classes I want to use inside my ui and it is as follows:
import 'package:get_it/get_it.dart';
import './core/Items_lists.dart';
GetIt locator = GetIt();
void setupLocator() {
locator.registerFactory(() => ItemList()) ;
}
And when I run the application to view the OrdersUI() I get a screen that looks like this:
It shows gray color instead of listing the items
what am I doing wrong here? why the items doesn't appear?
NOTE: I am using provider version 4.0.0
You can copy paste run full code below
Step 1: You can move ChangeNotifierProvider to MyApp
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (BuildContext context) => locator<ItemList>(),
),
],
child: MaterialApp(
Step 2: There is a bug , you missed place } , cause error
child: GestureDetector(
onTap: () {
print("CLICKED!");
child: Container(
should be
GestureDetector(
onTap: () {
print("CLICKED!");
},
child: Container(
working demo
full code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:get_it/get_it.dart';
GetIt locator = GetIt.instance;
void setupLocator() {
locator.registerFactory(() => ItemList());
}
void main() {
setupLocator();
runApp(MyApp());
}
class ItemList extends ChangeNotifier {
List items = [
{
"id": "1",
"type": "men",
"liked": true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price": 1,
},
{
"id": "2",
"type": "men",
"liked": true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price": 2,
},
{
"id": "3",
"type": "men",
"liked": true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price": 3,
},
{
"id": "4",
"type": "men",
"liked": true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price": 4,
},
{
"id": "5",
"type": "men",
"liked": true,
"cuisine": "Americain",
"img": "../../images/jeans.png",
"price": 5,
},
];
likeAndUnlike(id) {
items.forEach((item) {
if (item['id'] == id) {
item['liked'] = !item['liked'];
}
});
notifyListeners();
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (BuildContext context) => locator<ItemList>(),
),
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: OrdersUI(),
),
);
}
}
class LikedProduct extends StatelessWidget {
final productDetails;
LikedProduct({this.productDetails});
#override
Widget build(BuildContext context) {
print("productDetails ${productDetails["id"]}");
final size = MediaQuery.of(context).size;
print("insideLikedProject");
return Padding(
padding: EdgeInsets.only(bottom: 22),
child: GestureDetector(
onTap: () {
print("CLICKED!");
},
child: Container(
height: size.height * 0.15,
width: size.width * 0.9,
child: Row(
children: <Widget>[
Hero(
transitionOnUserGestures: true,
tag: productDetails['id'],
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.asset(
productDetails['img'],
width: size.width * 0.35,
height: size.height * 0.15,
fit: BoxFit.cover,
),
),
),
SizedBox(
width: 8,
),
SizedBox(
height: size.height * 0.13,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
productDetails['type'],
//style: style.headerStyle3,
),
Text(
productDetails['price'].toString() + " OMR",
/*style: style.textTheme
.copyWith(color: Theme.of(context).primaryColor),*/
),
],
),
)
],
),
),
));
}
}
class OrdersUI extends StatefulWidget {
#override
_OrdersUIState createState() => _OrdersUIState();
}
class _OrdersUIState extends State<OrdersUI> {
final totalCost = 0;
final jeansPrice = 0;
final jeansCounter = 0;
final standardDeliveryCost = 5;
final expressDeliveryCost = 15;
void _changeTotalPrice() {
setState(() {});
}
final productDetails;
_OrdersUIState({this.productDetails});
#override
Widget build(BuildContext context) {
final data = MediaQuery.of(context);
final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
title: Align(
alignment: Alignment.center,
child: Text(
'Title',
style: TextStyle(color: Colors.black),
)),
actions: <Widget>[],
backgroundColor: Colors.white,
),
body: Container(
width: data.size.width,
//height: data.size.height * 0.05,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Container(
color: Color.fromARGB(255, 81, 202, 238),
height: data.size.height * 0.05,
width: data.size.width,
alignment: Alignment.topCenter,
child: Align(
alignment: Alignment.center,
child: Text(
'Total : ${totalCost.toString()} OMR',
))),
),
],
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12),
child: Column(
children: <Widget>[
Consumer<ItemList>(
builder: (context, model, child) {
print("Inside Builder"); // doesn't get executed
return Container(
height: 500,
child: ListView.builder(
physics: ScrollPhysics(
parent: BouncingScrollPhysics()),
shrinkWrap: true,
itemCount: model.items.length,
itemBuilder: (context, index) {
print(model.items[index]["type"].toString());
print(
'Inside Item Builder'); // doesn't get executed
return Container(
height: 200,
width: 300,
child: LikedProduct(
productDetails: model.items[index],
),
);
},
),
);
},
),
],
),
),
Row(
children: <Widget>[
Expanded(
child: Container(
//margin: const EdgeInsets.only(left: 50.0, right: 50.0),
child: Divider(
height: 1,
thickness: 1,
color: Colors.grey.shade700,
),
),
)
],
),
],
)));
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}