簡體   English   中英

窗口小部件如何使動畫向下滑動?

[英]How to do widget slide down animation in flutter?

我想為小部件做一個slide-down動畫。 我從互聯網上看到了很多例子,但是沒有什么可以滿足我的要求。 這就是我所需要的。 以下是我制作的自定義小部件。

Widget Toast(String content, ToastType type) {
  return Column(
    children: <Widget>[
      Padding(
        padding: const EdgeInsets.all(50),
        child: Card(
          elevation: 10,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
          color: ToastColors[type.index],
          child: Padding(
            padding: const EdgeInsets.only(left: 15, right: 20, top: 10, bottom: 10),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                ToastIcons[type.index],
                SizedBox(
                  width: 15,
                ),
                Flexible(
                  child: Text(
                    content,
                    style: TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.w400,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    ],
  );
}

這是一個烤面包的布局。 我希望可以從應用程序中的任何位置進行訪問。 這就是為什么我為此創建了單獨的dart文件的原因。

我想要的是? 顯示小部件時,我希望烤面包布局向下滑動。 我不想循環播放或反轉動畫。 動畫完成后,小部件必須保持在最終位置。

我從對代碼的描述中推斷出,您希望能夠創建從屏幕頂部向下滑動的Toast,並且希望能夠在任何地方創建它。

您很幸運,顫振具有此功能! showGeneralDialog是您要尋找的。

這是一個例子:

import 'package:flutter/material.dart';

main() => runApp(TheApp());

class TheApp extends StatefulWidget {
  @override
  _TheAppState createState() => _TheAppState();
}

class _TheAppState extends State<TheApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        floatingActionButton: Builder(
          builder: (context) {
            return FloatingActionButton(
              child: Icon(
                Icons.add,
              ),
              onPressed: () {
                bool wasCompleted = false;
                showGeneralDialog(
                  context: context,
                  barrierDismissible: true,
                  transitionDuration: Duration(milliseconds: 500),
                  barrierLabel: MaterialLocalizations.of(context).dialogLabel,
                  barrierColor: Colors.black.withOpacity(0.5),
                  pageBuilder: (context, _, __) {
                    return TheToast();
                  },
                  transitionBuilder: (context, animation, secondaryAnimation, child) {
                    if (animation.status == AnimationStatus.completed) {
                      wasCompleted = true;
                    }

                    if (wasCompleted) {
                      return FadeTransition(
                        opacity: animation,
                        child: child,
                      );
                    } else {
                      return SlideTransition(
                        position: CurvedAnimation(
                          parent: animation,
                          curve: Curves.easeOut,
                        ).drive(Tween<Offset>(begin: Offset(0, -1.0), end: Offset.zero)),
                        child: child,
                      );
                    }
                  },
                );
              },
            );
          },
        ),
        body: Container(),
      ),
    );
  }
}

class TheToast extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Card(
        color: Colors.white,
        child: Padding(
          padding: EdgeInsets.all(10),
          child: Text(
            "I'm a Toast",
            style: TextStyle(color: Colors.black),
          ),
        ),
      ),
    );
  }
}

您可以使自己的函數類似於showGeneralDialog(也許是showToast),並使用適當的文本進行調用。 動畫結束后,我也使吐司淡了。 如果您只想讓它向上滑動,那會更加簡單,並且可以擺脫過渡邏輯的這一部分。 當您點按背景時,我也使吐司消失了,但是您可以禁用該吐司,而當您想隱藏對話框時,可以調用Navigator.pop(context)。

您也可以使用“覆蓋”條目直接執行此操作,但這絕對簡單。

Nvm。 我想到了。 首先,我創建了一個StatefulWidget ,並將其用作showToastWidget函數中的子showToastWidget

這是StatefulWidget

import 'package:flutter/material.dart';

class SlideToast extends StatefulWidget {
  final Widget _toast;

  SlideToast(this._toast);

  @override
  _SlideToastState createState() => _SlideToastState();
}

class _SlideToastState extends State<SlideToast> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<Offset> _offsetFloat;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 350),
    );

    _offsetFloat =
        Tween(begin: Offset(0.0, -0.03), end: Offset.zero).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Curves.fastOutSlowIn,
      ),
    );

    _offsetFloat.addListener(() {
      setState(() {});
    });

    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SlideTransition(
      position: _offsetFloat,
      child: widget._toast,
    );
  }
}

所需functionenumlist

enum ToastType { Info, Warning, Success, Error }

const List<Color> ToastColors = [
  Colors.blue,
  Colors.orange,
  Colors.green,
  Colors.redAccent
];

const List<Icon> ToastIcons = [
  Icon(
    Icons.info,
    color: Colors.white,
  ),
  Icon(
    Icons.info,
    color: Colors.white,
  ),
  Icon(
    Icons.check_circle,
    color: Colors.white,
  ),
  Icon(
    Icons.error,
    color: Colors.white,
  )
];

Widget Toast(String content, ToastType type) {
  return Column(
    children: <Widget>[
      Padding(
        padding: const EdgeInsets.only(top: 85),
        child: Card(
          elevation: 10,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
          color: ToastColors[type.index],
          child: Padding(
            padding:
                const EdgeInsets.only(left: 15, right: 20, top: 10, bottom: 10),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                ToastIcons[type.index],
                SizedBox(
                  width: 15,
                ),
                Flexible(
                  child: Text(
                    content,
                    style: TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.w400,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    ],
  );
}

最后像這樣調用showToastWidget

showToastWidget(
   Toast('Hello World!!!', ToastType.Warning),
   duration: Duration(seconds: 1),
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM