Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animation between Elevated and Outlined button

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?

like image 467
Valentin Vignal Avatar asked Feb 12 '26 13:02

Valentin Vignal


2 Answers

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

like image 176
Valentin Vignal Avatar answered Feb 15 '26 05:02

Valentin Vignal


Simply use AnimatedSwitcher widget

AnimatedSwitcher(
  child: _highlighted
      ? ElevatedButton(
          key: ValueKey("elevated"),
          onPressed: _onPressed,
          child: buttonContent,
        )
      : OutlinedButton(
          key: ValueKey("outlined"),
          onPressed: _onPressed,
          child: buttonContent,
        ),
)
like image 41
Sartaj Roshan Avatar answered Feb 15 '26 05:02

Sartaj Roshan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!