I'm developing an app to make meal reservations, and I have an ElevatedButton
that opens an alert when pressed. This alert is where the user is able to confirm the reservation. So, the alert has 2 text buttons, and I need that when the "sim" button is pressed, the ElevatedButton
changes from "Reservar" with green color to "Cancelar Reserva" with red color.
I tried this way but it doesn't work:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import '../components/meal_item.dart';
import '../models/day_of_week.dart';
import '../models/want_to_comment.dart';
import '../models/meal.dart';
import '../utils/app_routes.dart';
import '../data/dummy_data.dart';
enum StatusReserva { y, n }
Color statusToColor(StatusReserva value) {
Color color = Colors.green;
switch (value) {
case StatusReserva.n:
break;
case StatusReserva.y:
color = Colors.red;
break;
}
return color;
}
String statusToString(StatusReserva value) {
String title = 'Reservar';
switch (value) {
case StatusReserva.n:
break;
case StatusReserva.y:
title = 'Cancelar Reserva';
break;
}
return title;
}
class DaysOfWeekMealsScreen extends StatefulWidget {
final List<Meal> meals;
final StatusReserva status;
final Function(StatusReserva) onStatusChanged;
const DaysOfWeekMealsScreen({
Key? key,
required this.meals,
required this.status,
required this.onStatusChanged,
}) : super(key: key);
@override
State<DaysOfWeekMealsScreen> createState() => _DaysOfWeekMealsScreenState();
}
class _DaysOfWeekMealsScreenState extends State<DaysOfWeekMealsScreen> {
StatusReserva status = StatusReserva();
@override
void initState() {
super.initState();
status = widget.status;
}
@override
Widget build(BuildContext context) {
final dayOfWeek = ModalRoute.of(context)!.settings.arguments as DayOfWeek;
final dayOfWeekMeals = widget.meals.where((meal) {
return meal.days_of_week.contains(dayOfWeek.id);
}).toList();
void _incrementCount(BuildContext context) {
dayOfWeek.count ;
}
Future<void> _showMyDialog(BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
' ',
),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text(
'Confirmar reserva para o dia XX/XX/XX?',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontFamily: 'Raleway',
fontWeight: FontWeight.bold),
),
],
),
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
child: const Text('Sim'),
onPressed: () => {
_incrementCount,
Navigator.pop(context),
status = StatusReserva.y
},
),
TextButton(
child: const Text('Não'),
onPressed: () => Navigator.pop(context),
),
],
),
],
);
},
);
}
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
'assets/images/logo.png',
fit: BoxFit.contain,
height: 32,
),
Container(
padding: const EdgeInsets.all(8.0),
child: Text(dayOfWeek.title)),
],
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
margin: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () => {_showMyDialog(context)},
style: ButtonStyle(
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
)),
padding: MaterialStateProperty.all(const EdgeInsets.all(15)),
backgroundColor:
MaterialStateProperty.all(statusToColor(widget.status)),
),
child: Text(statusToString(widget.status)),
),
),
Expanded(
child: ListView.builder(
itemCount: dayOfWeekMeals.length,
itemBuilder: (ctx, index) {
return MealItem(dayOfWeekMeals[index]);
},
),
),
],
),
);
}
}
import 'package:apetit_project/models/want_to_comment.dart';
import 'package:apetit_project/screens/login_screen.dart';
import 'package:flutter/material.dart';
import 'screens/tabs_screen.dart';
import 'screens/days_of_week_meals_screen.dart';
import 'screens/meal_detail_screen.dart';
import 'screens/settings_screen.dart';
import 'screens/want_to_comment_screen.dart';
import 'screens/comment_screen.dart';
import 'utils/app_routes.dart';
import 'models/meal.dart';
import 'models/settings.dart';
import 'data/dummy_data.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Settings settings = Settings();
StatusReserva status = StatusReserva();
List<Meal> _gourmetMeals = [];
List<Meal> _lightMeals = [];
void _filterMeals(Settings settings) {
setState(() {
this.settings = settings;
});
}
void _reserveMeals(StatusReserva status) {
setState(() {
this.status = status;
});
}
void _toggleGourmet(Meal meal) {
setState(() {
_gourmetMeals.contains(meal)
? _gourmetMeals.remove(meal)
: _gourmetMeals.add(meal);
});
}
bool _isGourmet(Meal meal) {
return _gourmetMeals.contains(meal);
}
void _toggleLight(Meal meal) {
setState(() {
_lightMeals.contains(meal)
? _lightMeals.remove(meal)
: _lightMeals.add(meal);
});
}
bool _isLight(Meal meal) {
return _lightMeals.contains(meal);
}
@override
Widget build(BuildContext context) {
final ThemeData tema = ThemeData(
fontFamily: 'Raleway',
textTheme: ThemeData.light().textTheme.copyWith(
headline6: const TextStyle(
fontSize: 20,
fontFamily: 'Raleway',
fontWeight: FontWeight.bold,
),
),
);
return MaterialApp(
title: 'Appetit',
theme: tema.copyWith(
colorScheme: tema.colorScheme.copyWith(
primary: const Color.fromRGBO(222, 1, 59, 1),
secondary: const Color.fromRGBO(240, 222, 77, 1),
),
),
routes: {
AppRoutes.LOGIN: (ctx) => LoginScreen(),
AppRoutes.HOME: (ctx) => TabsScreen(_gourmetMeals, _lightMeals),
AppRoutes.WANT_TO_COMMENT: (ctx) => const WantToCommentScreen(),
AppRoutes.COMMENT: (ctx) => const CommentScreen(),
AppRoutes.DAYS_OF_WEEK_MEALS: (ctx) => DaysOfWeekMealsScreen(
meals: DUMMY_MEALS,
status,
_reserveMeals,
),
AppRoutes.MEAL_DETAIL: (ctx) => MealDetailScreen(
_toggleGourmet, _isGourmet, _toggleLight, _isLight),
AppRoutes.SETTINGS: (ctx) => SettingsScreen(settings, _filterMeals),
},
);
}
createMaterialColor(Color color) {}
}
CodePudding user response:
The StatusReserva status = StatusReserva.n;
should be in the State class _DaysOfWeekMealsScreenState
. And to change it use setState
. This value should never change if not inside a setState
.
The Sim
button onPressed
should be like the following (Also with fixes of an unintended Set
creation):
TextButton(
child: const Text('Sim'),
onPressed: () {
_incrementCount();
Navigator.pop(context);
setState(() => status = StatusReserva.y);
},
),
CodePudding user response:
To change the state of a widget you can use setState
enum StatusReserva { y, n }
Color statusToColor(StatusReserva value) {
Color color = Colors.green;
switch (value) {
case StatusReserva.n:
break;
case StatusReserva.y:
color = Colors.red;
break;
}
return color;
}
class StatusTest extends StatefulWidget {
const StatusTest({Key? key}) : super(key: key);
@override
State<StatusTest> createState() => _StatusTestState();
}
class _StatusTestState extends State<StatusTest> {
var status = StatusReserva.n;
Future<void> _showMyDialog(BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
' ',
),
content: SingleChildScrollView(
child: ListBody(
children: const <Widget>[
Text(
'Confirmar reserva para o dia XX/XX/XX?',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontFamily: 'Raleway',
fontWeight: FontWeight.bold),
),
],
),
),
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
child: const Text('Sim'),
onPressed: () => setState(() {
Navigator.pop(context);
status = StatusReserva.n;
}),
),
TextButton(
child: const Text('Não'),
onPressed: () => setState(() {
Navigator.pop(context);
status = StatusReserva.y;
}),
),
],
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
height: 100,
child: Container(
color: statusToColor(status),
child: const Center(
child: Text(
'Status color',
style: TextStyle(color: Colors.white),
)),
),
),
ElevatedButton(
onPressed: () {
_showMyDialog(context);
},
child: const Text('Show dialog'),
),
],
),
),
);
}
}