skip to Main Content

I want a button to change between ElevatedButton and OutlinedButton. I have this code snipped:

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  var _highlighted = false;

  void _onPressed() {
    setState(() {
      _highlighted = !_highlighted;
    });
  }

  @override
  Widget build(BuildContext context) {
    const buttonContent = Text('Button');
    return Scaffold(
      body: Center(
        child: _highlighted
            ? ElevatedButton(
                onPressed: _onPressed,
                child: buttonContent,
              )
            : OutlinedButton(
                onPressed: _onPressed,
                child: buttonContent,
              ),
      ),
    );
  }
}

Here is how it looks:

enter image description here

I would like the transition to be "smooth". When the button changes from one style to another, it would like it to be animated. How to do that?

2

Answers


  1. Chosen as BEST ANSWER

    I managed to get the desired effect using AnimatedTheme.

    Look at the widget AnimatedButton in the following code snippet:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          themeMode: ThemeMode.dark,
          darkTheme: ThemeData(
            brightness: Brightness.dark,
            outlinedButtonTheme: OutlinedButtonThemeData(
              style: OutlinedButton.styleFrom(
                foregroundColor: Colors.white,
                side: const BorderSide(color: Colors.white),
                padding: const EdgeInsets.all(8),
              ),
            ),
            elevatedButtonTheme: ElevatedButtonThemeData(
              style: ElevatedButton.styleFrom(
                foregroundColor: Colors.black,
                backgroundColor: Colors.white,
                padding: const EdgeInsets.all(32),
              ),
            ),
          ),
          home: const Home(),
        );
      }
    }
    
    class Home extends StatefulWidget {
      const Home({super.key});
    
      @override
      State<Home> createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      var _highlighted = false;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: AnimatedButton(
              highlighted: _highlighted,
              onPressed: () {
                setState(() {
                  _highlighted = !_highlighted;
                });
              },
              child: const Text('Button'),
            ),
          ),
        );
      }
    }
    
    class AnimatedButton extends StatelessWidget {
      const AnimatedButton({
        required this.child,
        required this.highlighted,
        required this.onPressed,
        super.key,
      });
    
      final Widget child;
      final bool highlighted;
      final VoidCallback onPressed;
    
      @override
      Widget build(BuildContext context) {
        final theme = Theme.of(context);
        return AnimatedTheme(
          data: theme.copyWith(
            outlinedButtonTheme: OutlinedButtonThemeData(
              style: highlighted
                  ? theme.elevatedButtonTheme.style
                  : theme.outlinedButtonTheme.style,
            ),
          ),
          child: OutlinedButton(
            onPressed: onPressed,
            child: child,
          ),
        );
      }
    }
    

    The result is (with "slow animation" enabled):

    enter image description here


  2. Simply use AnimatedSwitcher widget

    AnimatedSwitcher(
      child: _highlighted
          ? ElevatedButton(
              key: ValueKey("elevated"),
              onPressed: _onPressed,
              child: buttonContent,
            )
          : OutlinedButton(
              key: ValueKey("outlined"),
              onPressed: _onPressed,
              child: buttonContent,
            ),
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search