Home > Mobile >  How to change Elevated button's title and color onpressed
How to change Elevated button's title and color onpressed

Time:07-14

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

For further clarification

  • Related