最近有个需求从某个点弹出试图,(比如观看直播距屏幕左侧20px处弹出个礼物)。分别尝试了路由,主要是PopupRoute。平移动画。效果都不理想。故最终采用了自增宽度的一个动画效果。详细代码如下,这里简单记一下实现方式。
已知缺点:事先得设置一个最大宽度。不能随内容增大而增大。
效果如图:
bo8ux-bg6yh.gif
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController controller;
AnimationController transController;
Animation<double> transAnimation;
void _beginAnim() {
//开始执行动画
if (controller != null) {
controller.forward();
//5秒后消失
Future.delayed(Duration(seconds: 5),(){
if(transController!=null){
transController.forward();
}
});
}
}
//有个缺点
//这里的宽度只能写死
double toWidth = 162;
@override
void dispose() {
// TODO: implement dispose
super.dispose();
controller.dispose();
controller = null;
transController.dispose();
transController=null;
}
@override
void initState() {
// TODO: implement initState
super.initState();
controller = AnimationController(
duration: Duration(
milliseconds: 300,
),
lowerBound: 0.0,
upperBound: toWidth,
vsync: this);
transController=AnimationController(duration:Duration(
milliseconds: 300,
),vsync: this);
transAnimation=Tween(begin: 1.0,end: 0.0).animate(transController);
controller.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
Container(
width: double.infinity,
height: 400,
color: Colors.blue,
child: Stack(
children: <Widget>[
Positioned(
left: 12,
bottom: 30,
child:FadeTransition(
opacity: transAnimation,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: getBorderRadius(),
color: Colors.red,
),
width: controller.value,
height: 24,
child: Text(
controller.value == toWidth ? "收到礼物飞机x1" : "",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
),
),
),
)
)
],
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_beginAnim();
},
tooltip: 'Increment',
child: Icon(Icons.add),
), //
);
}
BorderRadius getBorderRadius() {
if (controller.value > (toWidth - 12)) {
return BorderRadius.all(Radius.circular(12));
} else {
return BorderRadius.only(
bottomRight: Radius.circular(12), topRight: Radius.circular(12));
}
}
}
网友评论