扩展和普通类型之间的颤动动画FAB

问题描述 投票:2回答:1

我想实现一个浮动操作按钮,该按钮可以在扩展尺寸和正常尺寸之间设置动画效果,如android的Messenger应用程序中所示:https://blog.usejournal.com/expand-collapse-fab-on-scrolling-like-googles-message-app-484df2d9d246

我该如何实现?我目前正在研究使用AnimatedSwitcher,FloatingActionButton.extended和FloatingActionButton小部件。

flutter floating-action-button flutter-animation
1个回答
1
投票

这是我使用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')));
      }
    }

这是我的实现,通过为两个FAB保留相同的Hero标签。

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

两者都有不同的结果,请根据需要尝试使用不同的动画曲线。更改子项的大小,设置“形状”边框或将mini:设置为true可获得更好的效果。

© www.soinside.com 2019 - 2024. All rights reserved.