web-dev-qa-db-fra.com

Flutter Animate Fab entre le type étendu et normal

J'aimerais mettre en place un bouton d'action flottante qui anime des tailles étendues et normales, comme indiqué dans Androids Messenger App: https://blog.usejournal.com/expand-collapse-fab-on-scrolling-lise Googles-Message-App-484DF2D9D246

Comment puis-je atteindre cet objectif? Je suis actuellement à la recherche de widgets d'animationdswitcher, de floatingactionbutton.extended et de flottatingbutton.

7
Ollie

Il suffit de changer entre Fab.extended et Normal Fab, il a une animation lors de la commutation de la FAB normale vers la FAB étendue, pas Visorsa.

isextend
            ? FloatingActionButton.extended(
                onPressed: _switchActionBar,
                label: Text("Text"))
            : FloatingActionButton(
                onPressed: _switchActionBar,
                child: Icon(Icons.add),
              )
1
Maciej Fiedler

Ceci est mon implémentation en utilisant AnimatedSwitcher.

 import 'package:flutter/material.Dart';

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

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }

    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
      bool isIcon = false;

      Widget _myWidget = FloatingActionButton(
        key: UniqueKey(),
        onPressed: () {},
        child: Icon(Icons.message),
      );
      void _d() {
        setState(() {
          _myWidget = isIcon
              ? FloatingActionButton(
                  mini: true,
                  key: UniqueKey(),
                  onPressed: () {},
                  child: Icon(Icons.messsage),
                )
              : FloatingActionButton.extended(
                  key: UniqueKey(),
                  onPressed: () {},
                  icon: Icon(Icons.message),
                  label: Text("Start chat"),
                );
          isIcon = !isIcon;
        });
      }

      Widget build(context) {
        return Scaffold(
            floatingActionButton: isIcon
                ? AnimatedSwitcher(
                    duration: Duration(
                      milliseconds: 100,
                    ),
                    transitionBuilder: (Widget child, Animation<double> animation) {
                      return FadeTransition(
                        child: child,
                        opacity:
                            animation.drive(CurveTween(curve: Curves.elasticOut)),
                      );
                    },
                    child: _myWidget,
                  )
                : AnimatedSwitcher(
                    duration: Duration(
                      milliseconds: 100,
                    ),
                    transitionBuilder: (Widget child, Animation<double> animation) {
                      return FadeTransition(
                        child: child,
                        opacity:
                            animation.drive(CurveTween(curve: Curves.easeOutQuint)),
                      );
                    },
                    child: _myWidget,
                  ),
            appBar: AppBar(),
            body: FlatButton(
                onPressed: () {
                  _d();
                },
                child: Text('Press here to change FAB')));
      }
    }

C'est ma mise en œuvre en gardant la même Hero étiquette pour les deux FABS.

import 'package:flutter/material.Dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool isIcon = false;

  Widget _myWidget = FloatingActionButton(
    heroTag: 'd',
    key: UniqueKey(),
    onPressed: () {},
    child: Icon(Icons.message),
  );
  void _d() {
    setState(() {
      _myWidget = isIcon
          ? FloatingActionButton(
              heroTag: 'b',
              key: UniqueKey(),
              onPressed: () {},
              child: Icon(Icons.message),
            )
          : FloatingActionButton.extended(
              heroTag: 'b',
              key: UniqueKey(),
              onPressed: () {},
              icon: Icon(Icons.mesage),
              label: Text("Start chat"),
            );
      isIcon = !isIcon;
    });
  }

  Widget build(context) {
    return Scaffold(
        floatingActionButton: _myWidget,
        appBar: AppBar(),
        body: FlatButton(
            onPressed: () {
              _d();
            },
            child: Text('Press here to change FAB')));
  }
}

Les deux donnent des résultats différents, essayez avec différentes courbes d'animation comme vous le souhaitez. Modifier la taille de l'enfant, régler la bordure de forme ou définir mini: égal à vrai pour obtenir un meilleur résultat.

1
cmd_prompter

voici ce que j'ai fait

(your widget should be Stateful for this to work)

ajoutez d'abord un booléen isExtended à votre widget

bool isExtended = false;

ajoutez ensuite une nouvelle fonction pour changer l'état de votre valeur isExtended

void _switchActionBar() {
    setState(
      () {
        isExtended = !isExtended;
      },
    );
  }

dernière initiale le FloatingActionButon comme ça

FloatingActionButton.extended(
      isExtended: isExtended,
      onPressed: (){},
      label: isExtended
          ? Row(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(right: 8.0),
                  child: Icon(Icons.add),
                ),
                Text("Start Editing"),
              ],
            )
          : Icon(Icons.add),
    );

et c'est tout, chaque fois que vous appelez _switchActionBar() votre bouton d'action flottant vous animera entre prolongé et normal.

0