flutter 直播礼物弹出动画

2020-08-05  本文已影响0人  林祖朋

最近有个需求从某个点弹出试图,(比如观看直播距屏幕左侧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));
    }
  }
}

上一篇下一篇

猜你喜欢

热点阅读