【发布时间】:2018-04-16 03:45:56
【问题描述】:
所以我使用小部件 Stack 创建了自己的抽屉,以便它出现在内容的顶部。我希望这个抽屉与小部件 Scaffold 抽屉(默认)具有相同的动画,以便我将动画放在这个抽屉上,但是当我点击菜单图标时动画不起作用。所以这是我的代码。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rencana_belanja/ui/common/gradient_app_bar.dart';
import 'package:rencana_belanja/ui/home/home_screen_body.dart';
class HomeScreen extends StatefulWidget {
@override
State createState() {
// TODO: implement createState
return new HomeScreenState();
}
}
class HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin{
bool isShow = false;
AnimationController _showingDrawerAnimation;
Animation<Size> _theDrawer;
@override
void initState() {
// TODO: implement initState
super.initState();
_showingDrawerAnimation = new AnimationController(
vsync: this,
duration: new Duration(milliseconds: 300)
);
_theDrawer = new SizeTween(
begin: new Size.fromWidth(0.0),
end: new Size.fromWidth(280.0)
).animate(new CurvedAnimation(
parent: _showingDrawerAnimation,
curve: Curves.ease
));
}
@override
Widget build(BuildContext context) {
Widget drawer = new Stack(
children: <Widget>[
new InkWell(
child: new Container(
color: Colors.black54
),
onTap: () async {
if (_showingDrawerAnimation.isCompleted) {
await _showingDrawerAnimation.reverse();
setState(() {
isShow = false;
});
}
},
),
new AnimatedBuilder(
animation: _theDrawer,
builder: (BuildContext context, Widget child) {
return new PreferredSize(
preferredSize: _theDrawer.value,
child: new SizedBox(
width: _theDrawer.value.width,
child: new Container(
decoration: new BoxDecoration(
boxShadow: [
new BoxShadow(
color: Colors.black45,
blurRadius: 7.0
)
],
gradient: new LinearGradient(
colors: [
const Color(0xFF02AAB0),
const Color(0xFF00CDAC)
],
begin: const FractionalOffset(0.0, 0.7),
end: const FractionalOffset(0.6, 0.3),
stops: [0.0, 1.0],
tileMode: TileMode.clamp
)
),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_showingDrawerAnimation.isAnimating ? new Container() : new Stack(
children: <Widget>[
new Image(
image: new AssetImage(
'assets/img/bokeh.jpg',
),
),
new Positioned(
bottom: 10.0,
left: 5.0,
child: new Text(
'Rencanakan kebutuhan belanjamu!',
style: new TextStyle(
color: Colors.white,
fontFamily: 'Ubuntu',
fontWeight: FontWeight.w500,
fontSize: 15.0,
)
),
)
],
),
_showingDrawerAnimation.isAnimating ? new Container() : new Container(
margin: const EdgeInsets.only(top: 12.0, bottom: 180.0),
padding: const EdgeInsets.symmetric(horizontal: 18.0),
child: new Column(
children: <Widget>[
new Row(
children: <Widget>[
new Icon(Icons.delete, color: Colors.white,),
new Container(width: 20.0,),
new Text('Tong Sampah', style: new TextStyle(
color: Colors.white,
fontFamily: 'Ubuntu',
fontWeight: FontWeight.w500,
fontSize: 16.0,
),)
],
),
new Divider(color: Colors.white,),
new Row(
children: <Widget>[
new Icon(Icons.help_outline, color: Colors.white,),
new Container(width: 20.0,),
new Text('Petunjuk Penggunaan', style: new TextStyle(
color: Colors.white,
fontFamily: 'Ubuntu',
fontWeight: FontWeight.w500,
fontSize: 16.0,
),)
],
),
new Divider(color: Colors.white,),
new Row(
children: <Widget>[
new Icon(Icons.person, color: Colors.white,),
new Container(width: 20.0,),
new Text('Hubungi Author', style: new TextStyle(
color: Colors.white,
fontFamily: 'Ubuntu',
fontWeight: FontWeight.w500,
fontSize: 16.0,
),)
],
),
new Divider(color: Colors.white,),
],
),
),
_showingDrawerAnimation.isAnimating ? new Container() : new Row(
children: <Widget>[
new Container(
width: 10.0,
),
new Text(
'Personalization',
style: new TextStyle(
color: Colors.white,
fontFamily: 'Ubuntu',
fontWeight: FontWeight.w500,
fontSize: 14.0,
)
),
],
),
_showingDrawerAnimation.isAnimating ? new Container() : new Divider(color: Colors.white,),
_showingDrawerAnimation.isAnimating ? new Container() : new Row(
children: <Widget>[
new Container(margin: const EdgeInsets.only(left: 15.0)),
new Icon(Icons.settings, color: Colors.white,),
new Container(width: 20.0,),
new Text('Pengaturan', style: new TextStyle(
color: Colors.white,
fontFamily: 'Ubuntu',
fontWeight: FontWeight.w500,
fontSize: 16.0,
),)
],
),
],
),
),
),
);
},
)
],
);
// TODO: implement build
return new Scaffold(
body: new Stack(
children: <Widget>[
new Column(
children: <Widget>[
new GradientAppBar(
title: 'Daftar Belanja',
isShow: isShow,
onDrawerShows: (bool value) async {
if (_showingDrawerAnimation.isDismissed) {
await _showingDrawerAnimation.forward();
setState(() {
isShow = true;
});
}
},
),
new HomeScreenBody()
],
),
new Positioned(
bottom: 20.0,
right: 15.0,
child: new GestureDetector(
onTap: () => print("tiesto"),
child: new CircleAvatar(
backgroundColor: Colors.red,
child: new Icon(
Icons.add,
color: Colors.white,
),
radius: 25.0,
),
)
),
isShow == true ? drawer : new Text(''),
],
),
);
}
}
唯一起作用的动画只有reverse一个。如何使 forward 动画正常工作?
注意:抱歉英语不好,这不是我的母语,所以我希望你能理解。谢谢
【问题讨论】:
-
好的做法是创建 drawer
Widget drawer = new Stack()或 build 函数之外的任何其他函数。 -
如果您使用 SizeTransition。代码会变得简单很多。 docs.flutter.io/flutter/widgets/SizeTransition-class.html
-
@ArnoldParge 是的,我知道这是一个很好的做法,但有时我需要在其中包含上下文。上下文仅在构建方法上可用。
-
上下文在构建函数之外也可用:)