Skip to content

Instantly share code, notes, and snippets.

@slightfoot
Last active April 16, 2020 16:07

Revisions

  1. slightfoot revised this gist Apr 14, 2020. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -124,9 +124,7 @@ class _AnimatedButtonState extends State<AnimatedButton>
    return MaterialButton(
    color: color,
    shape: _index == 0
    ? RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(4.0),
    )
    ? RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0))
    : StadiumBorder(),
    animationDuration: widget.animDuration,
    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
  2. slightfoot revised this gist Apr 14, 2020. 1 changed file with 0 additions and 6 deletions.
    6 changes: 0 additions & 6 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -144,12 +144,6 @@ class _AnimatedButtonState extends State<AnimatedButton>
    duration: widget.animDuration,
    switchInCurve: Interval(0.5, 1.0, curve: Curves.easeIn),
    switchOutCurve: Interval(0.0, 0.5, curve: Curves.easeOut),
    transitionBuilder: (Widget child, Animation<double> animation) {
    return FadeTransition(
    opacity: animation,
    child: child,
    );
    },
    child: _index == 0
    ? Padding(
    key: Key('text'),
  3. slightfoot created this gist Apr 14, 2020.
    173 changes: 173 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,173 @@
    // MIT License
    //
    // Copyright (c) 2020 Simon Lightfoot
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to deal
    // in the Software without restriction, including without limitation the rights
    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    // copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in all
    // copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    // SOFTWARE.
    //
    import 'package:flutter/material.dart';

    void main() => runApp(ExampleApp());

    class ExampleApp extends StatefulWidget {
    @override
    _ExampleAppState createState() => _ExampleAppState();
    }

    class _ExampleAppState extends State<ExampleApp> {
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
    primaryColor: Colors.indigo,
    accentColor: Colors.pinkAccent,
    ),
    home: Scaffold(
    appBar: AppBar(
    title: Text('Animated Button Example'),
    ),
    body: Center(
    child: Transform.scale(
    scale: 3.0,
    child: AnimatedButton(
    text: 'Press Me',
    icon: Icons.check,
    textTheme: ButtonTextTheme.accent,
    onPressed: () {
    print('pressed');
    },
    ),
    ),
    ),
    ),
    );
    }
    }

    class AnimatedButton extends StatefulWidget {
    const AnimatedButton({
    Key key,
    @required this.text,
    @required this.icon,
    this.onPressed,
    this.pauseDuration = const Duration(milliseconds: 1000),
    this.animDuration = const Duration(milliseconds: 300),
    this.textTheme = ButtonTextTheme.normal,
    }) : super(key: key);

    final String text;
    final IconData icon;
    final VoidCallback onPressed;
    final Duration pauseDuration;
    final Duration animDuration;
    final ButtonTextTheme textTheme;

    @override
    _AnimatedButtonState createState() => _AnimatedButtonState();
    }

    class _AnimatedButtonState extends State<AnimatedButton>
    with TickerProviderStateMixin {
    int _index = 0;

    Future<void> _onButtonPressed() async {
    if (_index == 1) {
    return;
    }
    setState(() => _index = 1);
    await Future.delayed(
    widget.pauseDuration.compareTo(widget.animDuration) >= 0
    ? widget.pauseDuration
    : widget.animDuration);
    widget.onPressed?.call();
    if (mounted) {
    setState(() => _index = 0);
    }
    }

    @override
    Widget build(BuildContext context) {
    final theme = Theme.of(context);
    Color color;
    TextTheme textTheme;
    IconThemeData iconTheme;
    switch (widget.textTheme) {
    case ButtonTextTheme.accent:
    color = theme.accentColor;
    textTheme = theme.accentTextTheme;
    iconTheme = theme.accentIconTheme;
    break;
    case ButtonTextTheme.primary:
    color = theme.primaryColor;
    textTheme = theme.primaryTextTheme;
    iconTheme = theme.primaryIconTheme;
    break;
    default:
    break;
    }
    return MaterialButton(
    color: color,
    shape: _index == 0
    ? RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(4.0),
    )
    : StadiumBorder(),
    animationDuration: widget.animDuration,
    materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
    padding: EdgeInsets.zero,
    minWidth: 0.0,
    onPressed: widget.onPressed != null ? _onButtonPressed : null,
    child: DefaultTextStyle(
    style: textTheme.button,
    child: IconTheme(
    data: iconTheme,
    child: AnimatedSize(
    duration: widget.animDuration,
    vsync: this,
    child: AnimatedSwitcher(
    duration: widget.animDuration,
    switchInCurve: Interval(0.5, 1.0, curve: Curves.easeIn),
    switchOutCurve: Interval(0.0, 0.5, curve: Curves.easeOut),
    transitionBuilder: (Widget child, Animation<double> animation) {
    return FadeTransition(
    opacity: animation,
    child: child,
    );
    },
    child: _index == 0
    ? Padding(
    key: Key('text'),
    padding: const EdgeInsets.symmetric(
    horizontal: 16.0,
    vertical: 8.0,
    ),
    child: Text(widget.text),
    )
    : Padding(
    key: Key('icon'),
    padding: const EdgeInsets.all(8.0),
    child: Icon(widget.icon),
    ),
    ),
    ),
    ),
    ),
    );
    }
    }