我想实现一个浮动操作按钮,该按钮可以在扩展尺寸和正常尺寸之间设置动画效果,如android的Messenger应用程序中所示:https://blog.usejournal.com/expand-collapse-fab-on-scrolling-like-googles-message-app-484df2d9d246
我该如何实现?我目前正在研究使用AnimatedSwitcher,FloatingActionButton.extended和FloatingActionButton小部件。
这是我使用
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可获得更好的效果。