我想为小部件制作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
文件的原因。
我想要什么? 显示小部件时,我希望烤面包布局向下滑动。我不想循环播放或反转动画。动画完成后,小部件必须保持在最终位置。
答案 0 :(得分:1)
我从您对代码的描述中推断出,您希望能够创建从屏幕顶部向下滑动的吐司,并且希望能够在任何地方创建它。
您很幸运,颤振具有此功能! showGeneralDialog
是您要寻找的。 p>
这是一个例子:
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)。
您也可以直接使用覆盖项来执行此操作,但这绝对简单。
答案 1 :(得分:0)
Nvm。我想到了。首先,我创建了一个StatefulWidget
并将其用作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,
);
}
}
必填function
,enum
,list
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),
);