push Main page to second page - flutter

I have five items on the main screen, and what I want to do when one is pressed it goes to the corresponding page. Not sure exactly how to use the InkWell function to be able to push the tap from the first main page to the second page. .
Not sure if I am on the right track with the code below or need to go into another direction.
Main.dart
import 'package:flutter/material.dart';
import './food_catefgories.dart';
import './main_categories_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Made in Canada Stuff',
theme: ThemeData(
primarySwatch: Colors.blue,
canvasColor: Color.fromRGBO(225, 254, 229, 1),
textTheme: ThemeData.light().textTheme.copyWith(
body1: TextStyle(
color: Color.fromRGBO(20, 51, 51, 1),
),
body2: TextStyle(
color: Color.fromRGBO(20, 51, 51, 1),
),
title: TextStyle(
fontSize: 20,
fontFamily: 'RobotoCondensed',
fontWeight: FontWeight.bold,
)),
),
home: MainCategoriesScreen(),
initialRoute: '/spalsh',
routes: {
'/splash': (context) => MainCategoriesScreen(),
'/one': (context) => OneCategoriesScreen(),
'/two': (context) => TwoCategoriesScreen(),
'/three': (context) => ThreeCategoriesScreen(),
'/four': (context) => FourCategoriesScreen(),
'/five': (context) => FiveCategoriesScreen(),
},
);
}
}
main_categories_screen.dart
import 'package:flutter/material.dart';
import './category_item.dart';
class Category {
final String id;
final String title;
final Color color;
const Category({
this.id,
this.title,
this.color = Colors.orange,
});
}
const MAINCAT_CATEGORIES = const [
Category(
id: 'c1',
title: "ONE",
color: Colors.purple,
),
Category(
id: 'c2',
title: "TWO",
color: Colors.red,
),
Category(
id: 'c3',
title: "THREE",
color: Colors.blue,
),
];
class MainCategoriesScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Made title'),
),
body: GridView(
padding: const EdgeInsets.all(25),
children: MAINCAT_CATEGORIES
.map((catData) => CategoryItem(
catData.title,
catData.color,
),
)
.toList(),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
),
),
);
}
}
category_item.dart
import 'package:flutter/material.dart';
import './main_categories_screen.dart';
class CategoryItem extends StatelessWidget {
final String title;
final Color color;
CategoryItem(this.title, this.color);
void selectCategory(BuildContext ctx) {
Navigator.of(ctx).push(
MaterialPageRoute(
builder: (_) {
return MainCategoriesScreen();
},),);
}
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => selectCategory(context),
splashColor: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(15),
child: Container(
padding: const EdgeInsets.all(15),
child: Text(title,
style: Theme.of(context).textTheme.title,
),
decoration: BoxDecoration(gradient: LinearGradient(
colors: [
color.withOpacity(0.7),
color,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(15),
),
),
);
}
}

You can navigate from one screen to another and pass the data using Navigate class
For Example i'm using in my app.
Navigator.push(context,MaterialPageRoute(builder:
(context) => Home(userRole: role)),
ModalRoute.withName('/home'));

Navigator.push(context,MaterialPageRoute(builder:
(context) => Home(userRole: role))),
or
Navigator.pushNamed(context, '/first');
Make sure before using second line you have to declared all page in your MaterialApp like
initialRoute: '/spalsh',
routes: {
'/': (context) => LoginScreen(),
'/spalsh':(context)=>SplashScreen(),
'/first': (context) => FirstScreen(),
'/leave': (context) => ApplyLeave(),
'/bill': (context) => ApplyBill(),
'/contact': (context) => ContactUs(),
'/four': (context) => ScreenFour(),
'/five': (context) => ScreenFive(),
'/six': (context) => ScreenSix(),
'/seven': (context) => ScreenSeven(),
},

//Navigate to other page with class name and parameters
Navigator.push(
context, MaterialPageRoute(builder: (context) => FoodCategoriesScreen(title:"Items")));
//class name is FoodCategoriesScreen and the parameter is title to which we are assigning a value "Items".
//Navigator through routes that you have specified in your code (without parameters)
Navigator.pushNamed(context, '/food');

Related

Dart Flutter: throw FlutterError.fromParts(<DiagnosticsNode>[

I'm making a program for calculations in flutter and when building the package, it throws me to the "debyg.dart" file and points to the line "throw FlutterError.fromParts(<DiagnosticsNode>[". So what should I do with this error. I'm still new to flutter, so I don't know much.
import 'package:flutter/material.dart';
import 'datchik/datchiki.dart';
import 'ThirdPage.dart';
import 'datchik/TCP10P.dart';
import 'datchik/TCP50P.dart';
import 'datchik/TCP100P.dart';
import 'datchik/TCP500P.dart';
import 'datchik/TCP1000P.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/',
routes: {
'/': (context) => const MyHome(),
'/datchiki': (context) => SecondPage(),
'/ThirdPage': (context) => ThirdPage(),
'/TCP10P': (context) => const TCP10P(),
'/TCP100P': (context) => const TCP100P(),
'/TCP50P': (context) => const TCP50P(),
'/TCP500P': (context) => const TCP500P(),
'/TCP1000P': (context) => const TCP1000P(),
},
),
);
}
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super (key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 214, 162, 248),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Главная страница",
style: TextStyle(fontSize: 20)),
TextButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/datchiki');
},
icon: const Icon(Icons.settings),
label: const Text('Датчики температур'),
),
ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/ThirdPage');
},
icon: const Icon(Icons.settings),
label: const Text('ТСП - 50П')
),
],
)
),
)
);
}
}
TCP-10P.dart The file in which the error appears
import 'package:flutter/material.dart';
import 'datchik/datchiki.dart';
import 'ThirdPage.dart';
import 'datchik/TCP10P.dart';
import 'datchik/TCP50P.dart';
import 'datchik/TCP100P.dart';
import 'datchik/TCP500P.dart';
import 'datchik/TCP1000P.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/',
routes: {
'/': (context) => const MyHome(),
'/datchiki': (context) => SecondPage(),
'/ThirdPage': (context) => ThirdPage(),
'/TCP10P': (context) => const TCP10P(),
'/TCP100P': (context) => const TCP100P(),
'/TCP50P': (context) => const TCP50P(),
'/TCP500P': (context) => const TCP500P(),
'/TCP1000P': (context) => const TCP1000P(),
},
),
);
}
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super (key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color.fromARGB(255, 214, 162, 248),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Главная страница",
style: TextStyle(fontSize: 20)),
TextButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/datchiki');
},
icon: const Icon(Icons.settings),
label: const Text('Датчики температур'),
),
ElevatedButton.icon(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.black),
foregroundColor: MaterialStatePropertyAll(Colors.white)
),
onPressed: () {
Navigator.pushNamed(context, '/ThirdPage');
},
icon: const Icon(Icons.settings),
label: const Text('ТСП - 50П')
),
],
)
),
)
);
}
}
Debug.dart The file where it throws me
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('No Material widget found.'),
ErrorDescription(
'${context.widget.runtimeType} widgets require a Material '
'widget ancestor.\n'
'In Material Design, most widgets are conceptually "printed" on '
"a sheet of material. In Flutter's material library, that "
'material is represented by the Material widget. It is the '
'Material widget that renders ink splashes, for instance. '
'Because of this, many material library widgets require that '
'there be a Material widget in the tree above them.',
),
ErrorHint(
'To introduce a Material widget, you can either directly '
'include one, or use a widget that contains Material itself, '
'such as a Card, Dialog, Drawer, or Scaffold.',
),
...context.describeMissingAncestor(expectedAncestorType: Material),
]);
I tried changing the SizedBox parameters, but nothing worked. Maybe I just did it wrong

Provider cannot get value

i am building mobile app using flutter. i try to use provider but it doesn't get the value.
this is the code for class change notifier
class StoreProvider with ChangeNotifier{
UserServices _userServices = UserServices();
StoreServices _storeServices = StoreServices();
User user = FirebaseAuth.instance.currentUser;
String userLocation = "";
String selectedStore;
String selectedStoreId;
getSelectedStore(storeName, storeId){
this.selectedStore = storeName;
this.selectedStoreId = storeId;
notifyListeners();
}
}
this is the code where i call this function
ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: snapshot.data.docs.map((DocumentSnapshot document) {
return InkWell(
onTap: (){
_storeData.getSelectedStore(document['shopName'], document['uid']);
pushNewScreenWithRouteSettings(
context,
settings: RouteSettings(name: VendorHomeScreen.id),
screen: VendorHomeScreen(),
withNavBar: true,
pageTransitionAnimation: PageTransitionAnimation.cupertino,
);
},
child: Padding(
padding: const EdgeInsets.only(top: 4, right: 4, left: 4),
child: Container(
width: 120,
child: Column(
children: [
SizedBox(
width: 120,
height: 100,
child: Card(
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Image.network(document['imageUrl'],))),
),
Container(
height: 35,
child: Text(document['shopName'], style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold,
), maxLines: 2, overflow: TextOverflow.ellipsis,),
),
],
),
),
),
);
}).toList(),
),
this is the code where i want to get the value that i put to the provider
var _store = Provider.of<StoreProvider>(context);
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
iconTheme: IconThemeData(
color: Colors.white,
),
actions: [
IconButton(
onPressed: () {},
icon: Icon(CupertinoIcons.search),
)
],
title: Text(
**//this is the error**
**//this is the error**
**//this is the error**
**//this is the error**
**//this is the error**
**_store.selectedStoreId,**
style:
TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
)
];
},
body: Center(
child: Text('vendor screen'),
),
));
and this is the main file
void main() async {
Provider.debugCheckInvalidValueType = null;
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AuthProvider()),
ChangeNotifierProvider(create: (_) => StoreProvider()),
],
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primaryColor: Colors.lightBlueAccent, fontFamily: 'Lato'),
initialRoute: SplashScreen.id,
routes: {
SplashScreen.id: (context) => SplashScreen(),
LoginPage.id: (context) => LoginPage(),
SignupPage.id: (context) => SignupPage(),
HomePage.id: (context) => HomePage(),
ResetPassword.id: (context) => ResetPassword(),
MainScreen.id: (context)=> MainScreen(),
VendorHomeScreen.id: (context) => VendorHomeScreen(),
},
);
}
}
i always get 'a non null A non-null String must be provided to a Text widget.'
i think the problem is when i put the value in the change notifier class and i try to get the value in other class, the value is null.
does anyone know what is the mistake??
thank you

Flutter/Dart - Text value not showing correctly

I am trying to create a shopping cart using provider and display the number of items currently in the cart on my homepage. When I create my cart icon with a text widget overlaid, the value being shown does not reflect the number of items in the cart.
Here is my code:
class OurShoppingBasketIcon extends StatelessWidget {
const OurShoppingBasketIcon({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ShoppingBasketScreen()),
);
},
child: Stack(
children: <Widget>[
new Icon(
Icons.shopping_cart_outlined,
color: Colors.white,
),
new Positioned(
right: 0,
child: new Container(
padding: EdgeInsets.all(1),
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(
minWidth: 12,
minHeight: 12,
),
child: Text(
context.read<ShoppingBasket>().items.length.toString(),
style: new TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
)
],
),
),
);
}
}
This is where the icon is implemented:
class OurHomePage extends StatefulWidget {
#override
_OurHomePageState createState() => _OurHomePageState();
}
class _OurHomePageState extends State<OurHomePage> {
#override
Widget build(BuildContext context) {
return Consumer<OurUser>(
builder: (_, user, __) {
return ChangeNotifierProvider<SignInViewModel>(
create: (_) => SignInViewModel(context.read),
builder: (_, child) {
return Scaffold(
appBar: AppBar(
title: Text("My app"),
actions: [
OurShoppingBasketIcon(),
IconButton(
icon: Icon(
Icons.logout,
color: Colors.white,
),
onPressed: () {
context.read<FirebaseAuthService>().signOut();
},
),
],
),
);
},
);
},
);
}
}
There are 2 items in the cart as of writing this:
But the icon on the homepage does not change:
Here is my main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
MultiProvider(
providers: [
Provider(
create: (_) => FirebaseAuthService(),
),
StreamProvider<OurUser>(
create: (context) =>
context.read<FirebaseAuthService>().onAuthStateChanged),
ChangeNotifierProvider.value(
value: ShoppingBasket(),
),
],
child: MaterialApp(theme: OurTheme().buildTheme(), home: OurHomePage()),
),
);
}
perhaps if you watch for the value it will be updated dynamically:
context.watch<ShoppingBasket>().items.length.toString(), //<-- watch instead of read
The OurHomePage needs to be wrapped in the Provider<ShoppingBasket>.
return Provider<ShoppingBasket>(
create: (context) => ShoppingBasket(),
child: Consumer<OurUser>(
builder: (_, user, __) {
return ChangeNotifierProvider<SignInViewModel>(
create: (_) => SignInViewModel(context.read),
builder: (_, child) {
return Scaffold(
appBar: AppBar(
title: Text("My app"),
actions: [
OurShoppingBasketIcon(),
IconButton(
icon: Icon(
Icons.logout,
color: Colors.white,
),
onPressed: () {
context.read<FirebaseAuthService>().signOut();
},
),
],
),
),
);
},
);
I forgot to NotifyListeners() in my Change Notifier class:
class ShoppingBasket extends ChangeNotifier {
Map<String, SingleBasketItem> _items = {};
Map<String, SingleBasketItem> get items {
return {..._items};
}
void addItem(String id) {
_items.putIfAbsent(
id,
() => SingleBasketItem(id),
);
notifyListeners(); //HERE
}

Why isn't the Provider Package changing the background image?

I've added the provider package to my application where I have two screen. When the user clicks on a small image on the app it changes the main background image on the other screen. I've called the Provider and classes on both screens but it just isn't returning the 'myValue' inside Positioned.fill.
Homepage screen with the background image that needs to change:
import 'package:flutter/material.dart';
import 'package:flutter_app_background/small_images.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: Text('Background Image', style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings, color: Colors.black,),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SmallImages()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Stack(
children: <Widget>
[
Positioned.fill(
child: GestureDetector(
child: Consumer<MyModel>(
builder: (context, myModel, child) {
return myModel.bgImage;
// return myValue;
},
),
),
),
],
),
);
}
}
class MyModel extends ChangeNotifier {
Image bgImage = Image.asset('images/background_image.jpeg', fit: BoxFit.fill);
}
Small Images screen where the user taps on small image to change the background in Homepage.
import 'package:flutter/material.dart';
import 'package:flutter_app_background/main.dart';
import 'package:provider/provider.dart';
class SmallImages extends StatefulWidget {
static int tappedGestureDetector = 1;
#override
_SmallImagesState createState() => _SmallImagesState();
}
class _SmallImagesState extends State<SmallImages> {
List<bool> isSelected;
void initState() {
isSelected = [true, false, false, false, false, false, false, false, false];
super.initState();
}
#override
Widget build(BuildContext context) {
final myModel = Provider.of<MyModel>(context,listen:true); //default for listen is `true`
return Scaffold(
appBar: AppBar(
title: Text('Small Image', style: TextStyle(
color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.arrow_left, color: Colors.black,),
onPressed: () {
Navigator.pop(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Material(
child: GestureDetector(
child: MaterialApp(
builder: (context, snapshot) {
return GridView.count(
crossAxisCount: 1,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 0.0,
crossAxisSpacing: 0.0,
children: [
GridView(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3,
childAspectRatio: MediaQuery
.of(context)
.size
.width /
(MediaQuery
.of(context)
.size
.height / 2),
),
children: [
GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 1;
});
myModel.bgImage = Image.asset('images/iceland_background.jpg');
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 1
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/nightsky_image.png',
),
),
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 2;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 2
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/own_image.png',
),
),
);
},
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 3;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 3
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/iceland_image.png',
),
),
);
},
),
].toList(),
),
],
);
}),
),
),
);
}
}
You should wrap material app with provider:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Provider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
);
)
}
}
if you want it to rebuild some widget on change of the MyModel, you should extend MyModel with ChangeNotifer like this:
class MyModel extends ChangeNotifier{
final bgImage = //someimage
and instead of Provider around the MaterialApp you should use ChangeNotifierProvider like this:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
);
)
}
}
after that you should include provider inside the widget like this:
#override
Widget build(BuildContext context) {
final mymodel = Provider.of<MyModel>(context); // injecting the provider
return Container ( .....
and you can use background image inside the container like this,
color:mymodel.bgImage
as soon as you will change the mymodel.bgImage widget will be rebuilt automatically.
if you are planning to rebuild specific widget inside the widget tree, you can remove injection such as this in this case final mymodel = Provider.of<MyModel>(context); and just wrap that specific widget with Consumer<MyModel> like this:
Container(
child:Consumer<MyModel>(
builder: (context, myModel, child) {
return Text("${myModel.text}"); // supposing that `text` is inside the `MyModel`
},
)
if you don't need child and context to use under the Container you can do it like this:
child:Consumer<MyModel>(
builder: (_, myModel, _) {
example of changing the myModel.bgImage will be something like this:
FlatButton(
onPressed: (val){
myModel.image = otherImage // changeing the value of my model while pressing on the button
}
)
changing the value of my model while pressing on the button will rebuild any widget which injects MyModel Provider and Provider listen property is set to true,(listen property is set to true by default)
example of listen property:
final mymodel = Provider.of<MyModel>(context,listen:false) //default for listen is `true`

Flutter Mobx multiple store not updating value in observer

I am using Mobx in my flutter application. I have multiple store. When I am trying to update some value in a store it is updating but not reflecting on UI.
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<LocationStore>(create: (_) => LocationStore()),
Provider<UserStore>(create: (_) => UserStore()),
Provider<RideStore>(create: (_) => RideStore()),
],
child: MaterialApp(
title: 'FLutter APp',
theme: myTheme(),
debugShowCheckedModeBanner: false,
// home: HomePage(
// title: 'Live Location'
// ),
initialRoute: WelcomeScreen.id,
routes: {
HomePage.id: (context) => HomePage(title: 'Home',),
ProfileScreen.id: (context) => ProfileScreen(),
WelcomeScreen.id: (context) => WelcomeScreen(),
RegistrationScreen.id: (context) => RegistrationScreen(),
LoginScreen.id: (context) => LoginScreen(),
FeedScreen.id: (context) => FeedScreen(),
RecordTrackScreen.id: (context) => RecordTrackScreen(),
SaveActivityScreen.id: (context) => SaveActivityScreen(),
UserProfileScreen.id: (context) => UserProfileScreen(),
RideDetailsScreen.id: (context) => RideDetailsScreen(),
StatsScreen.id: (context) => StatsScreen(),
FindInviteScreen.id: (context) => FindInviteScreen(),
CommentsScreen.id: (context) => CommentsScreen(),
},
),
);
}
}
screen
#override
Widget build(BuildContext context) {
final store = Provider.of<LocationStore>(context);
final rideStore = Provider.of<RideStore>(context);
final userStore = Provider.of<UserStore>(context);
return Scaffold(
appBar: AppBar(
title: Text('Record'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.info_outline),
onPressed: () {},
)
],
),
body: Observer(
builder: (_) => SingleChildScrollView(
child: Center(
child: Column(
children: <Widget>[
// Text('isPermitted - ${isPermitted}'),
Container(
child: isPermitted != null && isPermitted ? WeatherMainWidget() : Text(''),
height: (MediaQuery.of(context).size.height - 50.0) * 0.4,
),
Container(
height: (MediaQuery.of(context).size.height - 50.0) * 0.45,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
// Text('rideStore.getIsStarted - ${rideStore.getIsStarted} - $_isRunning'),
// if (rideStore.isStarted)
Divider(
indent: 10.0,
endIndent: 10.0,
thickness: 1.0,
color: color8,
),
Observer(
builder: (_) => Row(
children: [
Text('${rideStore.getSport.name}'),
Expanded(
flex: 1,
child: CustomIconButton(
iconData: rideStore.getSport.icon,
iconColor: Theme.of(context).primaryColor,
bgColor: Colors.transparent,
onPress: () {
SportBottomSheet(context, rideStore);
},
),
),
],
),
),
Container(
child: Visibility(
child: RecordTrackScreen(),
visible: rideStore.isStarted,
),
),
if (!rideStore.isStarted)
Container(
width: 70.0,
height: 70.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50.0),),
color: Theme.of(context).primaryColor,
),
child: Visibility(
visible: !rideStore.isStarted,
child: CustomIconButton(
iconData: Icons.play_arrow,
iconColor: Colors.white,
iconSize: 35.0,
onPress: () {
print('dsdsadsadsad');
startTrip(store, rideStore, userStore);
},
),
),
),
],
),
),
// ListenLocationWidget()
],
),
),
),
),
);
}
Widget SportBottomSheet(BuildContext context, RideStore rideStore) {
showModalBottomSheet(context: context, builder: (BuildContext bc) {
return Container(
color: Colors.white,
child: ListView.builder(itemCount: 2, itemBuilder: (ctx, index) {
final sport = rideStore.sports[index];
return GestureDetector(
child: ListTile(
leading: Icon(sport.icon, size: 30.0, color: Colors.black,),
title: Text(sport.name, style: TextStyle(
fontSize: 20.0,
color: Colors.black
),),
onTap: () {
print('SportBottomSheet $sport');
rideStore.selectedSport = new Sport(
sport.icon,
sport.name
);
rideStore.recentSport = rideStore.recentSport;
Navigator.pop(context);
print('sport ${rideStore.getSport.name}');
},
),
);
}),
);
});
}
ride store
class Sport{
final IconData icon;
final String name;
Sport(this.icon, this.name);
}
List<Sport> sports = [
new Sport(Icons.directions_walk_outlined, 'Walk'),
new Sport(Icons.motorcycle, 'Ride'),
];
#observable
Sport recentSport;
#observable
Sport selectedSport;
#computed
Sport get getSport {
if (selectedSport != null)
return selectedSport;
if (recentSport != null)
return recentSport;
return sports[0];
}
When I am checking getSport value in onTap method it is showing selected value but it is not updating on UI.
Thanks
Try changing your #computed to #action
#action
Sport get getSport {
if (selectedSport != null)
return selectedSport;
if (recentSport != null)
return recentSport;
return sports[0];
}
or maybe use ObservableList or ObservableFuture
Use ObservableList like this
#observable
ObservableList<Sport> sports =[Sport(Icons.directions_walk_outlined, 'Walk'), new Sport(Icons.motorcycle, 'Ride'),];