So, i'm building this app where i need to use a DropdownButton in an Alert. My widget is Stateful and i'm calling SetState, but still when i click into the DropdownItem it doesn't change in the Button. Can anydody help please? code below:
// ignore_for_file: use_key_in_widget_constructors, avoid_print, unrelated_type_equality_checks
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:apetit_project/models/app_user.dart';
import 'package:apetit_project/models/reservation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../models/meal.dart';
import '../utils/app_routes.dart';
class MealItem extends StatefulWidget {
final Meal meal;
MealItem(
this.meal,
);
@override
State<MealItem> createState() => _MealItemState();
}
class _MealItemState extends State<MealItem> {
final List<Reservation> _items = [];
String dropDownValue = '11:30';
List<Reservation> get items => [..._items];
final AppUser? appUser = const AppUser(
id: 'PedroNovoTeste',
email: 'email',
company: 'GTFoods',
);
void addReservation(Reservation reservation) {
// var resBody = {};
// resBody["cnpj"] = "1234567";
final future = http.post(
Uri.parse(
'http://172.16.30.120:8080/ords/apiteste/integrafoods/cadastra-empresa'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
"cnpj": reservation.user,
"razao": reservation.company,
"fantasia": reservation.opcao,
}),
);
future.then((response) {
_items.add(reservation);
});
}
void _newReservation() {
final newReservation = Reservation(
user: appUser!.id,
date: DateTime.now().add(const Duration(days: 2)),
opcao: widget.meal.id,
company: appUser!.company,
resTime: dropDownValue);
addReservation(newReservation);
print(newReservation.user);
print(newReservation.date);
print(newReservation.opcao);
print(newReservation.company);
print(newReservation.isReserved);
print(newReservation.resTime);
}
void _selectMeal(BuildContext context) {
Navigator.of(context)
.pushNamed(
AppRoutes.MEAL_DETAIL,
arguments: widget.meal,
)
.then((result) {
if (result == null) {
print('Sem resultado!');
} else {
print('O nome da refeição é $result.');
}
});
}
List<DropdownMenuItem<String>> get dropdownItems {
List<DropdownMenuItem<String>> menuItems = [
const DropdownMenuItem(value: "11:30", child: Text("11:30")),
const DropdownMenuItem(value: "12:00", child: Text("12:00")),
const DropdownMenuItem(value: "12:30", child: Text("12:30")),
const DropdownMenuItem(value: "13:00", child: Text("13:00")),
const DropdownMenuItem(value: "13:30", child: Text("13:30")),
];
return menuItems;
}
@override
Widget build(BuildContext context) {
final reservation = Provider.of<Reservation>(context);
final date = DateTime.now().add(const Duration(days: 2));
String formattedDate = DateFormat('dd/MM/yyyy').format(date);
return InkWell(
onTap: (widget.meal.descricao == 'Reservar')
? () {
showDialog(
context: context,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)),
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
gradient: LinearGradient(
colors: [
Colors.white.withOpacity(0.2),
Colors.grey.withOpacity(0.2),
Colors.black.withOpacity(0.2),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SingleChildScrollView(
child: ListBody(
children: <Widget>[
ListTile(
title: Padding(
padding: const EdgeInsets.only(top: 15),
child: Image.asset(
'assets/images/logo.png',
fit: BoxFit.contain,
height: 80,
),
),
),
Column(
children: [
Text(
(reservation.isReserved == false)
? 'Confirmar reserva para o dia $formattedDate no restaurante administrativo da empresa GTFoods(Matriz) para o horário'
: 'Você já possui uma reserva para o dia $formattedDate no restaurante administrativo da empresa GTFoods(Matriz), deseja cancelar sua reserva?',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 15,
fontFamily: 'Raleway',
fontWeight: FontWeight.bold),
),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
DropdownButton<String>(
value: dropDownValue,
items: <String>[
'11:30',
'12:00',
'12:30',
'13:00',
'13:30',
].map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
dropDownValue = newValue!;
});
},
),
const Text('?')
],
),
],
),
const SizedBox(
height: 10,
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
if (reservation.isReserved == false)
ElevatedButton(
child: const Text('Sim'),
onPressed: () {
_newReservation();
reservation.toggleReserved();
Navigator.pop(context);
},
),
if (reservation.isReserved == true)
ElevatedButton(
child: const Text('Sim'),
onPressed: () {
print(reservation.isReserved);
reservation.toggleReserved();
Navigator.pop(context);
},
),
ElevatedButton(
child: const Text('Não'),
onPressed: () => Navigator.pop(context),
),
],
),
ListTile(
title: Image.asset(
'assets/images/logo_gttech.png',
fit: BoxFit.contain,
height: 40,
),
),
],
),
),
],
),
),
);
},
);
}
: () => _selectMeal(context),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
elevation: 0,
margin: const EdgeInsets.only(right: 0, left: 0),
child: Column(
children: [
Stack(
children: [
ClipRRect(
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(15),
// topRight: Radius.circular(15),
// bottomLeft: Radius.circular(15),
// bottomRight: Radius.circular(15),
// ),
child: Image.asset(
widget.meal.imageUrl,
height: (widget.meal.descricao == 'Reservar') ? 50 : 73,
width: double.infinity,
fit: BoxFit.cover,
),
),
Container(
height: (widget.meal.descricao == 'Reservar') ? 0 : 73,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: FractionalOffset.centerRight,
end: FractionalOffset.centerLeft,
colors: [
Colors.grey.withOpacity(0.0),
Colors.black.withOpacity(0.9),
],
stops: const [0.0, 1.0],
),
),
),
Positioned(
bottom: (widget.meal.descricao == 'Reservar')
? 7
: (widget.meal.descricao == 'Feijoada')
? 15
: (widget.meal.descricao == 'X Salada')
? 15
: 0,
left: (widget.meal.descricao == 'Reservar') ? 95 : 10,
child: Container(
width: (widget.meal.descricao.length > 22)
? 300
: (widget.meal.descricao.length > 20)
? 210
: (widget.meal.descricao == 'Reservar')
? 210
: (widget.meal.descricao == 'Bife Americano')
? 150
: (widget.meal.descricao ==
'Feijão Tropeiro')
? 150
: (widget.meal.descricao.length > 14)
? 200
: 150,
padding: const EdgeInsets.symmetric(
vertical: 5,
horizontal: 15,
),
child: Text(
widget.meal.descricao,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
color: Colors.white,
),
softWrap: true,
overflow: TextOverflow.fade,
),
),
),
],
),
],
),
),
);
}
}
Any clues on why its not changing state please? I
m trying and i cant figure out where
s the problem. I need that when i select an item it changes in the button but it`s not working
CodePudding user response:
Wrap your Dialog
with StatefulBuilder
and use its setState.
StatefulBuilder(builder: (context, setState) {
return Dialog();
},)