How to Create a Reusable Widget Card Flutter? - android

I want to create a Card that is reusable with Image. Am I on the right track in the new type of Card? I do not know how to put the Image on the card. all the question regarding the reusable widget card type in stackoverflow and youtube seems old and i dont know if it is truly working in the newer version.
Prototype Figma of My vision of Card in the HomePage
Here is the example for the clarifcation of the image on the background
this is the previous code that I want to be scrapped because they are too many.
Container(
padding: const EdgeInsets.all(8),
color: const Color.fromARGB(255, 75, 175, 78),
child: Center(
child: TextButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
const SecondPage(
plantname: 'Bell Pepper')));
},
child: const Text(
"Bell Pepper",
style: TextStyle(
fontSize: 19,
fontFamily: 'RobotoMedium',
color: Color(0xffeeeeee)),
)),
)),
This the new type of Card that I want to be the reusable. But I dont know how to put the image and make it better.
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/cli_commands.dart';
class ListViewCard extends StatelessWidget {
final String title;
final void Function()? onTap;
final Image imageOfPlant;
const ListViewCard(
{super.key,
required this.title,
required this.onTap,
required this.imageOfPlant,
});
#override
Widget build(BuildContext context) {
return Card(
color: const Color.fromARGB(255, 75, 175, 78),
elevation: 0,
margin: const EdgeInsets.all(8),
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: InkWell(
splashColor: Colors.lightGreenAccent.withAlpha(30),
onTap: onTap,
//sizedBox of the card
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
width: 150,
height: 200,
child: Text(title,
style: const TextStyle(
fontSize: 19,
fontFamily: 'RobotoMedium',
color: Color(0xffeeeeee)),// textstyle
),),//text //SizedBox
], // <widget>[]
), // column
), //inkwell
); // card
}
}

Make a asset folder in your project like this
Add you image(jpeg, png or other) to this folder
Go to pubspec.yaml & add your asset path
To add assets to your application, add an assets section, like this:
assets:
- assets/
Make this changes in your ListViewCard widget:
import 'package:flutter/material.dart';
class ListViewCard extends StatelessWidget {
final String title;
final void Function()? onTap;
final String imageOfPlant; //Change to String
const ListViewCard(
{super.key,
required this.title,
required this.onTap,
required this.imageOfPlant,
});
#override
Widget build(BuildContext context) {
return Card(
color: const Color.fromARGB(255, 75, 175, 78),
elevation: 0,
margin: const EdgeInsets.all(8),
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: InkWell(
splashColor: Colors.lightGreenAccent.withAlpha(30),
onTap: onTap,
//sizedBox of the card
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.asset(
imageOfPlant,
height: 200,
width: 150,
fit: BoxFit.cover,
),
SizedBox(
width: 150,
height: 50,
child: Center(
child: Text(title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 19,
fontFamily: 'RobotoMedium',
color: Color(0xffeeeeee)),// textstyle
),
),),//text //SizedBox
], // <widget>[]
), // column
), //inkwell
); // card
}
}
Use your card
ListViewCard(
title: 'Lotus', onTap: () {}, imageOfPlant: 'assets/image.jpg')
OUTPUT:

You can use Stack widget for this,
class ListViewCard extends StatelessWidget {
final String title;
final void Function()? onTap;
final Image imageOfPlant;
const ListViewCard({
super.key,
required this.title,
required this.onTap,
required this.imageOfPlant,
});
#override
Widget build(BuildContext context) {
return Card(
color: const Color.fromARGB(255, 75, 175, 78),
elevation: 0,
margin: const EdgeInsets.all(8),
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: InkWell(
splashColor: Colors.lightGreenAccent.withAlpha(30),
onTap: onTap,
//sizedBox of the card
child: Stack(
children: [
Positioned.fill( // or positioned with top.left,bottom,right
child: imageOfPlant,
),
Align(
alignment: Alignment.bottomCenter,//based on your need
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
width: 150,
height: 200,
child: Text(
title,
style: const TextStyle(
fontSize: 19,
fontFamily: 'RobotoMedium',
color: Color(0xffeeeeee)), // textstyle
),
), //text //SizedBox
], // <widget>[]
),
),
],
), // column
), //inkwell
); // card
}
}
Also GridTile has similar look.

Instead of pass image widget inside constructor, pass its path, here I use asset image you can also network image too. Try this:
class ListViewCard extends StatelessWidget {
final String title;
final void Function()? onTap;
final String imageOfPlantPath;
const ListViewCard({
super.key,
required this.title,
required this.onTap,
required this.imageOfPlantPath,
});
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 2,
),
borderRadius: BorderRadius.all(Radius.circular(20))),
child: InkWell(
splashColor: Colors.lightGreenAccent.withAlpha(30),
onTap: onTap,
child: Container(
height: 300,
width: 150,
clipBehavior: Clip.antiAliasWithSaveLayer,
alignment: Alignment.bottomCenter,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(imageOfPlantPath),
fit: BoxFit.cover),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: LayoutBuilder(builder: (context, constraints) {
return Container(
alignment: Alignment.center,
width: constraints.maxWidth,
height: constraints.maxHeight * 0.5,
decoration: BoxDecoration(
color: Color.fromARGB(255, 75, 175, 78),
border: Border(
top: BorderSide(
color: Colors.black,
width: 2,
),
),
),
child: Text(
title,
style: const TextStyle(
fontSize: 19,
fontFamily: 'RobotoMedium',
color: Color(0xffeeeeee)), // textstyle
),
);
}), //text //S,
),
), //inkwell
); // card
}
}
Note: inside LayoutBuilder you can play with height and do what you want, I set half of the image here.
Instead of using Image as DecorationImage, you can use Stack that #YeasinSheikh said blew.

Related

What can I do so that no matter how long the text all will have same starting alignment?

I do a stateless widget category_card which is going to use four times.
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class CategoryCard extends StatelessWidget {
final String svgSrc;
final String title;
final VoidCallback press;
const CategoryCard(
{Key? key,
required this.svgSrc,
required this.title,
required this.press})
: super(key: key);
#override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(13),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(13),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.15),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3), // changes position of shadow
),
],
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: press,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
const Spacer(),
SvgPicture.asset(
svgSrc,
height: 100,
width: 100,
),
const Spacer(),
Text(
title,
style: Theme.of(context).textTheme.subtitle1!.copyWith(
fontWeight: FontWeight.w800,
fontSize: 15,
color: Colors.blueGrey[900]),
),
],
),
),
),
),
),
),
);
}
}
My output is alright, but the text part for long text such as medical condition the word is not align with the shorter word such as allergy. What can I do so that no matter how long the text all will have same starting alignment?
enter image description here
you can use Column property for making all it's item at the same point
Column(
crossAxisAlignment: CrossAxisAlignment.start, // or you can change it depends your need
children: [

Bottomsheet not allowing the container to show its properties in Flutter

I want to have a draggable bottom sheet for which I have written the code. But the problem is bottom sheet is shown properly but the body has a container and that is not shown. Can somebody help me with the same. If I run the code without bottomsheet it runs properly. I am unable to figure out where is the problem
import 'package:flutter/material.dart';
class HomePage1 extends StatelessWidget {
const HomePage1({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
return Scaffold(
backgroundColor: const Color(0xFF1E2129),
body: Stack(
children: [
Positioned.fill(
top: 150,
child: Container(
height: height * .4,
width: double.maxFinite,
color: const Color(0xFF1E2129),
child: Row(
children: [
const SizedBox(width: 24),
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
/* image: DecorationImage(
image: AssetImage('images/p1.png'),
),*/
border: Border.all(
color: const Color(0xFF3B414F), width: 1.0),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: const Icon(
Icons.message,
color: Color(0xFFBBFFF3),
size: 15,
),
),
const SizedBox(
width: 12,
),
const Text(
'Somnio Software',
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold,
),
)
],
),
),
),
],
),
bottomSheet: DraggableScrollableSheet(
builder: (BuildContext context, ScrollController scrollController) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32),
color: Colors.blue,
child: Column(
children: [
Text(
'DIRECT MESSAGES',
style: TextStyle(
color: Colors.grey.shade800,
fontWeight: FontWeight.bold,
fontSize: 10),
),
],
),
),
);
/*Container(
color: Colors.green,
child: ListView.builder(
controller: scrollController,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.all(5),
child: Card(
child: ListTile(
title: Text('Item $index'),
)),
);
}),
);*/
},
initialChildSize: .6,
),
);
}
}
DraggableScrollableSheet is always display in bottom no need to attached with bottom sheet,
Just drag into stack (as mentioned below)
Stack(
alignment: AlignmentDirectional.topStart,
children: [
Positioned.fill(
top: 150,
child: Container(
height: height * .4,
width: double.maxFinite,
color: const Color(0xFF1E2129),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(width: 24),
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
/* image: DecorationImage(
image: AssetImage('images/p1.png'),
),*/
color: Color(0xFF1E2129),
border: Border.all(
color: const Color(0xFF3B414F), width: 1.0),
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: const Icon(
Icons.message,
color: Color(0xFFBBFFF3),
size: 15,
),
),
const SizedBox(
width: 12,
),
const Text(
'Somnio Software',
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold,
),
)
],
),
),
),
DraggableScrollableSheet(
builder: (BuildContext context, ScrollController scrollController) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32),
color: Colors.blue,
child: Column(
children: [
Text(
'DIRECT MESSAGES',
style: TextStyle(
color: Colors.grey.shade800,
fontWeight: FontWeight.bold,
fontSize: 10),
),
],
),
),
);
/*Container(
color: Colors.green,
child: ListView.builder(
controller: scrollController,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return Container(
padding: EdgeInsets.all(5),
child: Card(
child: ListTile(
title: Text('Item $index'),
)),
);
}),
);*/
},
initialChildSize: .6,
)
],
),
See the Output...
you should try a function called bottom Model sheet and make it use in your project..
https://api.flutter.dev/flutter/material/showModalBottomSheet.html
you can find it on flutter api

Change the color of particular card on taping it in flutter?

I am using flutter I want to change the color of a particular card when I tap on it, not all the cards at the same time. The code is attached below. I am glad if someone helps.
...
Widget options(context,String title,String subtitle,String price,
String info, String plan) {
return GestureDetector(
child: Container(
height: 166,
width: 119,
child: Card(
color: Colors.white,
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
Container(
width: 120,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(7),
topRight: const Radius.circular(7),
),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 8, top: 8),
child: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
color: Color.fromRGBO(255, 255, 255, 1),
fontSize: 15,
fontFamily: 'CeroPro',
fontWeight: FontWeight.bold),
),
),
),
)
],
),
),
),
);
}
}
...
You could use a stateful widget.
So it would look something like this
class MyCard extends StatefulWidget {
MyCard(this.title, this.subtitle, this.price, this.info, this.plan);
String title;
String subtitle;
String price;
String info;
String plan;
#override
_MyCardState createState() => _MyCardState();
}
class _MyCardState extends State<MyCard> {
// initial color
Color color = Colors.white;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
//where newColor is the color it turns to
color = newColor;
});
},
child: Container(
height: 166,
width: 119,
child: Card(
// color is now a variable
color: color,
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
Container(
width: 120,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(7),
topRight: const Radius.circular(7),
),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 8, top: 8),
child: Text(
// to access the stateful widget's parameters, use widget.<parameter>
widget.title,
textAlign: TextAlign.center,
style: TextStyle(
color: Color.fromRGBO(255, 255, 255, 1),
fontSize: 15,
fontFamily: 'CeroPro',
fontWeight: FontWeight.bold),
),
),
),
],
),
),
),
);
}
}
You can try this also:
import 'package:flutter/material.dart';
class Testing extends StatefulWidget {
const Testing({Key? key}) : super(key: key);
#override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
bool isColor1Changed = false;
bool isColor2Changed = false;
bool isColor3Changed = false;
#override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
child: Row(
children: [
GestureDetector(
onTap: () {
setState(() {
isColor1Changed = !isColor1Changed;
});
},
child: options(context, "POPULAR", "Monthly", "\$4.99",
"3 Days Free Trail", "plan", isColor1Changed),
),
const SizedBox(width: 6),
GestureDetector(
onTap: () {
setState(() {
isColor2Changed = !isColor2Changed;
});
},
child: options(context, "83% OFF", "YEARLY", "\$9.99",
"\$0.83 / MONTH", "plan", isColor2Changed),
),
const SizedBox(width: 6),
GestureDetector(
onTap: () {
setState(() {
isColor3Changed = !isColor3Changed;
});
},
child: options(context, "50% OFF", "LIFE TIME", "\$19.99",
"\$39.98", "plan", isColor3Changed),
),
],
),
);
}
Widget options(context, String title, String subtitle, String price,
String info, String plan, bool isChangeColor) {
return GestureDetector(
child: Container(
height: 166,
width: 119,
child: Card(
color: isChangeColor ? Colors.lightBlue : Colors.white,
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
Container(
width: 120,
decoration: const BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(7),
topRight: Radius.circular(7),
),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 8, top: 8),
child: Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromRGBO(255, 255, 255, 1),
fontSize: 15,
fontFamily: 'CeroPro',
fontWeight: FontWeight.bold),
),
),
),
],
),
),
),
);
}
}

Provider not displaying updated state in another screen usng change notifier provider

im using provider and change notifier, the problem is when i change the state and notifiy listeners in the same file the user interface is updated, but when i try to access the same data from the model in another screen it still keeps the original or first version and not the updated version, the class in the other file is even using change notifier provider and a consumer just as the file with the modal class inside but is not changing the value, its only keeping the initial value, the second file only has changenotifierprovider and consumer, but it only displays the initial not the updated but the first file with the model class, and change notifier function is displaying the updated version in its widgets
And this is my second screen, which only displays the intial states even after they are updated in the frst screen
import 'package:flutter/material.dart';
import 'package:hotel_search/common/theme.dart';
import 'package:hotel_search/sliding_bottom_sheet_content.dart';
import 'package:hotel_search/home_page.dart';
import 'package:provider/provider.dart';
class BookScreen extends StatefulWidget {
#override
_BookScreenState createState() => _BookScreenState();
}
class _BookScreenState extends State<BookScreen> {
#override
void initState() {
super.initState();
/*Future.delayed(Duration(milliseconds: 1000)).then((v) {
Navigator.pop(context);
});*/
}
#override
Widget build(BuildContext context) {
final themeData = HotelConceptThemeProvider.get();
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
elevation: 0,
titleSpacing: 0,
backgroundColor: Colors.white,
title: Text(' ',
style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 20,
))),
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 40,
),
Container(
width: MediaQuery.of(context).size.width - 100,
height: 100,
child: Image.asset(
"assets/images/brand.png",
width: 0,
height: 0,
fit: BoxFit.cover,
)),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding:
EdgeInsets.only(left: 20, top: 20, bottom: 20),
width: MediaQuery.of(context).size.width,
child: Text('Review \nYour Booking',
style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 30,
))),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding: EdgeInsets.only(left: 20, top: 20),
width: MediaQuery.of(context).size.width,
child: Text("HOTEL NAME",
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20,
fontWeight: FontWeight.w700,
))),
Row(children: <Widget>[
Consumer<MyModel>(
builder: (context, myModel, children) {
return Container(
height: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text(
myModel.datesChosen.toString(),
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))),
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text(myModel.roomtype.toString(),
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)),
),
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text("CHECK IN AND OUT TIME",
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))),
Container(
padding:
EdgeInsets.only(left: 20, top: 5),
width: 200,
child: Text("TYPE OF ROOM CHOSEN",
style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)))
]));
}),
Spacer(),
Container(
margin: EdgeInsets.only(right: 20),
width: 150,
height: 120,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("img/card.jpg"),
fit: BoxFit.cover),
color: Colors.grey[300],
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(
0, 3), // changes position of shadow
)
]))
]),
SizedBox(height: 60),
Divider(
height: 25,
color: Colors.grey[300],
),
SizedBox(height: 20),
Container(
color: Color(0xff008d4b),
height: 60,
width: MediaQuery.of(context).size.width - 50,
child: FlatButton(
onPressed: () {
/*...*/
},
child: Text(
"Book Now",
style: TextStyle(
color: Colors.white,
fontFamily: 'Montserrat',
fontSize: 20,
),
),
),
)
]),
)))));
}
}
this is the part of my first where i created my changenotifier, theres more but it was long so i just added this part, but all widgets here display the updated state
class MyModel with ChangeNotifier{
String datesChosen = "Click here";
String checkin;
String checkout;
String email;
String name;
String roomtype = "Click here";
String phonenumber;
String hotelname;
void updateData1 (data){
datesChosen = data;
print(datesChosen);
notifyListeners();
}
void updateData2 (data){
roomtype = data;
print(roomtype);
notifyListeners();
}
in your second screen you're using
ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
....
)
which means you're actually creating a new Model, not reusing the one of your first page (They're unrelated and changing one won't change the other), I don't know how you call the second screen so this is more speculative but you doul pass the model from the previous screen to the second and then use ChangeNotifierProvider<MyModel>.value(), that will register the same model and notify both pages when a change occurs
in the first screen
onTap: Navigator.of(context).push(
MaterialPageRoute(
builder: BookScreen(Provider.of<MyModel>(context, listen: false))
)
);
now in the second screen
class BookScreen extends StatefulWidget {
final MyModel model;
BookScreen(this.model);
#override
_BookScreenState createState() => _BookScreenState();
}
class _BookScreenState extends State<BookScreen> {
#override
void initState() {
super.initState();
/*Future.delayed(Duration(milliseconds: 1000)).then((v) {
Navigator.pop(context);
});*/
}
#override
Widget build(BuildContext context) {
final themeData = HotelConceptThemeProvider.get();
return ChangeNotifierProvider<MyModel>.value(
value: widget.model,
....
)
Obviously if you created the provider MyModel at the beginning of your app (above your first MaterialApp) you don't need all this logic and could simply use it everywhere

Provider not displaying updated state in another screen

so im using provider and change notifier, the problem is when i change the state and notifiy listeners in the same file the user interface is updated, but when i try to access the same data from the model in another screen it still keeps the original or first version and not the updated version, the class in the other file is even using change notifier provider and a consumer just as the file with the modal class inside but is not changing the value, its only keeping the initial value, the second file only has changenotifierprovider and consumer, but it only displays the initial not the updated but the first file with the model class, and change notifier function is displaying the updated version in its widgets
this is the part of my first where i created my changenotifier, theres more but it was long so i just added this part, but all widgets here display the updated state
class MyModel with ChangeNotifier{
String datesChosen = "Click here";
String checkin;
String checkout;
String email;
String name;
String roomtype = "Click here";
String phonenumber;
String hotelname;
void updateData1 (data){
datesChosen = data;
print(datesChosen);
notifyListeners();
}
void updateData2 (data){
roomtype = data;
print(roomtype);
notifyListeners();
}
And this is my second screen, which only displays the intial states even after they are updated in the frst screen
import 'package:flutter/material.dart';
import 'package:hotel_search/common/theme.dart';
import 'package:hotel_search/sliding_bottom_sheet_content.dart';
import 'package:hotel_search/home_page.dart';
import 'package:provider/provider.dart';
class BookScreen extends StatefulWidget {
#override
_BookScreenState createState() => _BookScreenState();
}
class _BookScreenState extends State<BookScreen> {
#override
void initState() {
super.initState();
/*Future.delayed(Duration(milliseconds: 1000)).then((v) {
Navigator.pop(context);
});*/
}
#override
Widget build(BuildContext context) {
final themeData = HotelConceptThemeProvider.get();
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
home:Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => Navigator.of(context).pop(),
),
elevation: 0,
titleSpacing: 0,
backgroundColor: Colors.white,
title: Text(' ' ,style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 20,
))
)
,
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: MediaQuery.of(context).size.height,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 40,),
Container(
width: MediaQuery.of(context).size.width - 100,height: 100,
child:Image.asset(
"assets/images/brand.png",
width: 0,
height:0,
fit: BoxFit.cover,)),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding: EdgeInsets.only(left:20,top:20, bottom: 20),
width: MediaQuery.of(context).size.width,
child:Text('Review \nYour Booking' ,style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 30,
))
),
Divider(
height: 25,
color: Colors.grey[300],
),
Container(
padding: EdgeInsets.only(left:20,top:20),
width: MediaQuery.of(context).size.width,
child:Text("HOTEL NAME" ,style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20,
fontWeight: FontWeight.w700,
))
),
Row(
children: <Widget>[
Consumer<MyModel>(
builder: (context, myModel, children){
return
Container(
height: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text(myModel.datesChosen.toString() ,style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))
),
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text(myModel.roomtype.toString(), style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)),
)
,
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text("CHECK IN AND OUT TIME" ,style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
))),
Container(
padding: EdgeInsets.only(left:20,top:5),
width: 200,
child:Text("TYPE OF ROOM CHOSEN" ,style: TextStyle(
fontSize: 13,
fontFamily: 'Montserrat',
)))
]
)
);}),
Spacer(),
Container(
margin: EdgeInsets.only(right:20),
width: 150 ,
height:120,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("img/card.jpg"), fit: BoxFit.cover),
color: Colors.grey[300],
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10), boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3), // changes position of shadow
)
])
)
]
),
SizedBox(height: 60),
Divider(
height: 25,
color: Colors.grey[300],
),
SizedBox(height:20),
Container(
color: Color(0xff008d4b),
height: 60,
width: MediaQuery.of(context).size.width -50,
child:FlatButton(
onPressed: () {
/*...*/
},
child: Text(
"Book Now", style: TextStyle(
color: Colors.white,
fontFamily: 'Montserrat',
fontSize: 20,
),
),
),
)
]
),
)
)
)));
}
}
Have a look here at one of my more detailed answers about using the Provider. I think what you're missing is wrapping the application with a Provider Widget and calling setState(() {}); when you make those changes.
P.S. Please use Ctrl + Alt + L inside the editor to indent the code properly before asking a question. What you posted is barely readable. Also, you might wanna consider splitting up your code into multiple files and not just create the whole app in main.dart. You know... just some organizing here and there.

Categories

Resources