Different button will take me through different pages in Flutter - flutter

I'm working on a flutter project. I have a multiple button (Container wrap in Inkwell) using only one button in code and in List. I have tried to handle multiple buttons work in a List. But there is an error showing on the onTap function.
import 'package:flutter/material.dart';
import '../Ambulance/AmbulanceHome.dart';
import '../Blood Bank/BloodHome.dart';
import '../CreateCase/CaseHome.dart';
import '../Doctor Appoinment/HomeScreen.dart';
class BottomHomePage extends StatelessWidget {
List<FeaturesList> featuresList = [
FeaturesList('assets/BloodBank.jpg', 'Blood Bank', (context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) {
return HomeScreen();
},
),
);
}),
FeaturesList('assets/BloodBank.jpg', 'Doctor Appoinment', (context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) {
return HomeScreen();
},
),
);
}),
FeaturesList('assets/BloodBank.jpg', 'Create a Case', (context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) {
return HomeScreen();
},
),
);
}),
FeaturesList('assets/BloodBank.jpg', 'Ambulance', (context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) {
return HomeScreen();
},
),
);
}),
];
// void selectFeatures(BuildContext context) {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (_) {
// return HomeScreen();
// },
// ),
// );
// }
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFD9E4EE),
body: Padding(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Container(
width: double.infinity,
height: 150,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor.withOpacity(0.8),
borderRadius: BorderRadius.circular(20),
),
child: const Text(
'Fade-in logo of our project added here',
textAlign: TextAlign.center,
),
),
const SizedBox(height: 20),
Container(
alignment: AlignmentDirectional.topStart,
child: Text(
"Features",
style: Theme.of(context).textTheme.headline6,
),
),
const SizedBox(height: 20),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(
featuresList.length,
(index) {
return Column(
children: [
InkWell(
onTap: () => featuresList.callback?.call(context),
child: Container(
width: 150,
height: 150,
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(50),
// color: Theme.of(context)
// .colorScheme
// .primaryContainer
// .withOpacity(0.4),
),
child: Image.asset(featuresList[index].icon),
),
),
Text(featuresList[index].name),
],
);
},
),
),
),
],
),
),
);
}
}
class FeaturesList {
final String icon;
final String name;
final Function(BuildContext) callback;
FeaturesList(
this.icon,
this.name,
this.callback,
);
}
I have tried to use the navigation route in the List, but when I try to call the function called callback (which is defined in Features List class).
The error is on the line:
onTap: () => featuresList.callback?.call(context),
redline on the callback
Error message:
The getter 'callback' isn't defined for the type 'List'.
Try importing the library that defines 'callback', correcting the name to the name of an existing getter, or defining a getter or field named 'callback'.

featuresList is a List, so it does not have callback property. You should use
onTap: () => featuresList[index].callback?.call(context)

Related

Flutter Sqflite Toggling between Screens based on Login Status creates null operator used on null value error

I am trying to toggle between Login Screen and HomeScreen based on the user status. The logic seems to be working as long as I don't put HomeScreen.
I replaced HomeScreen with a different screen to check and the app works as it should. It displays different screens on hot restart based on the user's login status. But as soon as I try to put HomeScreen I get null operator used on null value error.
Here is the toggle logic.
class Testing extends StatefulWidget {
const Testing({super.key});
#override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: TodoServiceHelper().checkifLoggedIn(),
builder: ((context, snapshot) {
if (!snapshot.hasData) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
if (snapshot.hasError) {
print(snapshot.hasError);
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
if (snapshot.data!.isNotEmpty) {
print(snapshot.data);
return RegisterPage();
// returning HomePage gives null check operator used on null value error
} else
return Login();
}),
);
}
}
Here is the HomeScreen
class HomePage extends StatefulWidget {
String? username;
HomePage({this.username});
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final GlobalKey<FormState> formKey = GlobalKey();
TextEditingController termController = TextEditingController();
void clearText() {
termController.clear();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(
onPressed: () {
User loginUser =
User(username: widget.username.toString(), isLoggedIn: false);
TodoServiceHelper().updateUserName(loginUser);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) => Login()));
},
icon: Icon(Icons.logout),
color: Colors.white,
)
],
title: FutureBuilder(
future: TodoServiceHelper().getTheUser(widget.username!),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
return Text(
'Welcome ${snapshot.data!.username}',
style: TextStyle(color: Colors.white),
);
}),
),
body: SingleChildScrollView(
child: Column(children: [
Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Form(
key: formKey,
child: Column(
children: <Widget>[
TextFormField(
controller: termController,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
enabledBorder: OutlineInputBorder(),
labelText: 'search todos',
),
),
TextButton(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ShowingSerachedTitle(
userNamee: widget.username!,
searchTerm: termController.text,
)),
);
print(termController.text);
clearText();
setState(() {});
},
child: Text(
'Search',
)),
Divider(
thickness: 3,
),
],
),
),
),
],
),
Container(
child: Stack(children: [
Positioned(
bottom: 0,
child: Text(
' done Todos',
style: TextStyle(fontSize: 12),
),
),
IconButton(
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CheckingStuff(userNamee: widget.username!)),
);
setState(() {});
},
icon: Icon(Icons.filter),
),
]),
),
Divider(
thickness: 3,
),
Container(
child: TodoListWidget(name: widget.username!),
height: 1000,
width: 380,
)
]),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Color.fromARGB(255, 255, 132, 0),
onPressed: () async {
await showDialog(
barrierDismissible: false,
context: context,
builder: ((context) {
return AddNewTodoDialogue(name: widget.username!);
}),
);
setState(() {});
},
child: Icon(Icons.add),
),
);
}
}
The function used to return user with loginStatus true
Future<List<User>> checkifLoggedIn() async {
final Database db = await initializeDB();
final List<Map<String, Object?>> result = await db.query(
'users',
where: 'isLoggedIn = ?',
whereArgs: ['1'],
);
List<User> filtered = [];
for (var item in result) {
filtered.add(User.fromMap(item));
}
return filtered;
}
the problem is here
you used ! sign on a nullable String , and this string is nullable,
try to use this operation (??) so make it
widget.username??"" by this line you will check if the user name is null it will be replaced by an empty string.

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
}

Return variable from current screen to previous screen

So I am implementing a 'settings' view in my Flutter app. The idea is all settings will appear in a ListView, and when the user will click on a ListTile, a showModalBottomSheet will pop where the user will be able to manipulate the setting. The only problem I am having is I am unable to migrate the showModalBottomSheet to a separate class as I cannot make the new function (outside the class) return the manipulated setting variable. This has lead to a messy code, all in a single class.
class Page extends StatefulWidget {
Page({Key key}) : super(key: key);
#override
_Page createState() => _Page();
}
class _Page extends State<Page> {
var value;
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
ListTile(
title: Text("Age"),
trailing: Text(value),
onTap: () {
setState(() {
value = _valueSelector(); // This doesn't work, but to give an idea what I want
});
},
),
],
);
}
}
int _valueSelector(context) { // Doesn't return
var age = 0;
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Wrap(
children: [
Column(
children: <Widget>[
Slider(
value: age.toDouble(),
min: 0,
max: 18,
divisions: 18,
onChanged: (value) {
setState(() {
age = value.toInt();
});
},
),
],
),
],
);
});
},
).whenComplete(() {
return age; // Not sure if return is supposed to be here
});
}
How can I implement showModalBottomSheet in a separate class and just make it return the variable representing the setting chosen by the user?
You can try the below code,
First, create a class custom_bottom_sheet.dart and add the below code. You can use it everywhere in the project. And also use this library modal_bottom_sheet: ^0.2.0+1 to get the showMaterialModalBottomSheet.
customBottomSheet(BuildContext context, {#required Widget widget}) async {
return await showMaterialModalBottomSheet(
context: context,
backgroundColor: AppColors.transparent_100,
barrierColor: AppColors.black_75,
isDismissible: false,
enableDrag: true,
builder: (_, ScrollController scrollController) {
return widget;
},
);
}
Sample example code:
Create another class called bottom_sheet_example.dart and add the below code.
class BottomSheetExample {
static Future getSheet(BuildContext _context,
{ValueChanged<bool> onChanged}) async {
await customBottomSheet(
_context,
widget: SafeArea(
child: Container(
padding: EdgeInsets.only(left: 40.0, right: 40.0),
height: 170.0,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(27.0),
topRight: Radius.circular(27.0))),
child: Container(
padding: EdgeInsets.only(top: 32),
child: Column(
children: [
Text("Were you at Queen Victoria Building?"),
SizedBox(height: 48),
Row(
children: [
Expanded(
child: RaisedButton(
child: Text("No"),
onPressed: () {
Navigator.of(_context).pop();
onChanged(false);
},
),
),
SizedBox(width: 18),
Expanded(
child: RaisedButton(
child: Text("Yes"),
onPressed: () {
Navigator.of(_context).pop();
onChanged(true);
},
),
),
],
),
SizedBox(height: 24),
],
),
),
)),
);
}
}
Button click to show the bottom sheet
#override
Widget build(BuildContext context) {
return Scaffold(
body: yourBodyWidget(),
bottomNavigationBar: Container(
height: 40,
width: double.infinity,
child: FlatButton(
onPressed: () {
/// call BottomSheetExample class
BottomSheetExample.getSheet(
context,
onChanged: (bool result) async {
///
/// add your code
},
);
},
child: Text("show bottom sheet")),
),
);
}
In onChanged callback you can return your value(obj/String/num/bool/list).
Thank you!

Flutter, how to call Dialog function from another class

what is the proper way to call Dialog function from another class.
I have been searching this topic for a while but seems none of them are my answer.
my Dialog has a little complicated logic for server communicating and some paginations
so this code is going to be long for just one dart file. so I want to separate them.
and I need the some dialog animations so I picked the showGeneralDialog()
I also saw the example dialog implementaion using StatefulBuilder() which can use setState,
but this problem is it is not able to use initState()
for now, what I did is below
dart1 file
import 'package:aaa/bbb/some_dialog_file.dart'
as someDialog;
GestureDetector(
onTap: () async{
var result =
await someDialog.displayDialogOKCallBack(
context,
);
},
child: Container(
width: 60,
height: 60,
child: Icon(
Icons.comment,
size: 38,
),
),
)
dart2 file
Future<dynamic> displayDialogOKCallBack(BuildContext context) async {
return await showGeneralDialog(
barrierLabel: "Label",
barrierDismissible: true,
// barrierColor: ,
transitionDuration: Duration(milliseconds: 400),
context: context,
pageBuilder: (context, anim1, anim2) {
return StatefulBuilder(builder: (context, setState) {
return Scaffold(
body: SafeArea(
),
);
});
},
transitionBuilder: (context, anim1, anim2, child) {
return SlideTransition(
position:
Tween(begin: Offset(0, 1), end: Offset(0, -0.02)).animate(anim1),
child: child,
);
},
);
}
so my question is I want to build very clean animation dialog
which is logically separated from base class file and it has to have initState(), and setState()
how could I acheive this ? thanks
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Container(
child: RaisedButton(
onPressed: () {
someDialog(context);
},
child: Text("click"),
),
);
}
Future<dynamic> someDialog(BuildContext context) async {
return await showGeneralDialog(
barrierLabel: "Label",
barrierDismissible: true,
context: context,
pageBuilder: (context, anim1, anim2) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
// List
AnotherClassDialog(),
],
),
],
),
),
),
);
});
}
}
class AnotherClassDialog extends StatefulWidget {
#override
_AnotherClassDialogState createState() => _AnotherClassDialogState();
}
class _AnotherClassDialogState extends State<AnotherClassDialog> {
Color color;
#override
void initState() {
// TODO: implement initState
super.initState();
color = Colors.black;
}
#override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
RaisedButton(
onPressed: () {
setState(() {
color = Colors.red;
});
},
),
Container(
width: 100,
height: 100,
color: color,
),
RaisedButton(
onPressed: () {
setState(() {
color = Colors.green;
});
},
)
],
),
);
}
}
I use a custom dialog in my app in some classes and had the same problem.
You should define a dialog and pass context and other variables to it and call it everywhere you want.
You can define a dialog like this :
showCustomDialog(BuildContext context, String title, String description) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
title,
textAlign: TextAlign.right,
),
content: SingleChildScrollView(
child: Text(
description,
style: Theme.of(context).textTheme.bodyText1,
textAlign: TextAlign.right,
),
),
actions: [
FlatButton(
child: Text(
'ok',
style: Theme.of(context).textTheme.bodyText2.copyWith(
color: Theme.of(context).accentColor,
),
),
onPressed: () => Navigator.of(context).pop(),
),
],
actionsPadding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
);
});
}
and use it everywhere you want like this :
InkWell(
child: Icon(
Icons.error_outline,
size: 17,
),
onTap: () => showCustomDialog(context,"text1" , "text2") ,
),
I hope my answer will help you.

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'),];