flutter - 在 Flutter 中通过动画缓慢显示小部件
问题描述
我有一个小部件,单击它会显示另一个小部件,第二次它会关闭。我需要添加一些动画,以便我可以看到打开或关闭。现在它只是非常快速/立即打开和关闭。
我的代码:
Padding(
padding: const EdgeInsets.only(left: 13, right: 13, top: 13),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 2,
blurRadius: 3,
offset: Offset(0, 3), // changes position of shadow
),
],
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 8, right: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'DIAGNOSIS',
style: TextStyle(
color: kPrimaryColor,
fontFamily: 'PoppinsMedium',
fontSize: 14),
),
showB
? GestureDetector(
onTap: () {
print('false');
setState(() {
showB = false;
});
},
child: Icon(
Icons.keyboard_arrow_up_outlined))
: GestureDetector(
onTap: () {
print('true');
setState(() {
showB = true;
});
},
child: Icon(
Icons.keyboard_arrow_down_outlined))
],
),
),
showB
? Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 8),
child: Container(
width: Width * 0.9,
child: Divider(
color: Colors.grey,
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 8, right: 8, bottom: 8, top: 2),
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 10, left: 7, bottom: 5),
child: Text('Diagnosis',
textAlign: TextAlign.left,
style: TextStyle(fontFamily: 'PoppinsRegular', color: kPrimaryColor,)),
),
Container(
width: Width * 0.92 ,
child: TextFormField(
onChanged: (value) {
},
onSaved: (value) {},
style: TextStyle(
fontSize: 15,
color: kPrimaryColor,
fontFamily: 'UbuntuRegular'),
decoration: new InputDecoration(
suffixIcon: IconButton(
icon: Icon(
Icons.search_outlined,
color: Color(0xffbdbdbd),
),
),
border: new OutlineInputBorder(
borderSide:
const BorderSide(color: Color(0xffbdbdbd), width: 1),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
enabledBorder: new OutlineInputBorder(
borderSide:
const BorderSide(color: Color(0xffbdbdbd), width: 1),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
filled: true,
hintStyle: new TextStyle(
color: Color(0xffbdbdbd), fontFamily: 'UbuntuRegular'),
hintText: "Enter Diagnosis",
fillColor: Colors.white70,
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: kPrimaryColor, width: 1),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 10, left: 7, bottom: 5),
child: Text('Comments',
textAlign: TextAlign.left,
style: TextStyle(fontFamily: 'PoppinsRegular', color: kPrimaryColor,)),
),
Container(
width: Width * 0.92 ,
child: TextFormField(
maxLines: 5,// when user presses enter it will adapt to it
onChanged: (value) {
},
onSaved: (value) {},
style: TextStyle(
fontSize: 15,
color: kPrimaryColor,
fontFamily: 'UbuntuRegular'),
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderSide:
const BorderSide(color: Color(0xffbdbdbd), width: 1),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
enabledBorder: new OutlineInputBorder(
borderSide:
const BorderSide(color: Color(0xffbdbdbd), width: 1),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
filled: true,
hintStyle: new TextStyle(
color: Color(0xffbdbdbd), fontFamily: 'UbuntuRegular'),
hintText: "Enter Comments",
fillColor: Colors.white70,
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: kPrimaryColor, width: 1),
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
),
),
),
Align(
alignment: Alignment.centerRight ,
child: Padding(
padding: const EdgeInsets.only(top: 13),
child: Container(
decoration: BoxDecoration(
color: kPrimaryColor,
shape: BoxShape.circle,
),
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(
Icons.add,
size: 25.0,
color:Colors.white
),
)
),
)
),
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.only(top: 15, left: 7, bottom: 5),
child: RawMaterialButton(
onPressed: () {
print('sad');
setState(() {
showA = false;
showB = false;
showC = true;
showD = false;
});
},
elevation: 2.0,
fillColor: Colors.white,
child: Icon(
Icons.check_outlined,
size: 35.0,
color:kPrimaryColor
),
padding: EdgeInsets.all(15.0),
shape: CircleBorder(),
),
),
)
],
),
),
)
],
)
: Container()
],
),
),
),
),
),
),
我只想让容器像轻弹一样打开或关闭。那么如何添加动画以使其关闭或打开速度稍慢或带有一些动画?
解决方案
这更像是一个基于意见的问题。但一种简单的方法是Implicit Animations
在 Flutter 中使用。
对于您的情况,您可以使用AnimatedSize
.
首先,添加with TickerProviderStateMixin
到您的State<T>
类定义中。比如像这样,
class MyAppState extends State<MyApp> with TickerProviderStateMixin {
然后,你有一个列的第二个孩子是Column
这样的
showB ? Column( ..... ) : Container()
删除条件和其他情况Container
并将其更改为此,
Column( ..... )
现在,将它包裹Column
在一个AnimatedSize
和这样的Container
小部件中,
AnimatedSize(
vsync: this,
duration: Duration(milliseconds: 250),
child: Container(
height: showB ? null : 0,
child: Column( ..... ), // This is the same widget from above
)
)
现在,您的元素应该会自动生成动画。
此代码可能难以理解,因此请查看此pastebin以获取完整代码。
请注意,我已经删除了kPrimaryColor
andWidth
变量,因为您没有在代码中提供它们。
检查此 gif 以了解它是如何工作的。
现在,这是一个非常简单的动画,你绝对可以让它变得更好。阅读更多关于Flutter 中的隐式动画。
推荐阅读
- r - R循环使用data.table
- node.js - 我有一个问题,我的用户可以输入很长的数字并得到那个数量,我不知道如何解决它
- spring-boot - 春季启动测试。@DirtiesContext 注解关闭 HikariPool
- yocto - yocto 生成到 /lib64 的符号链接
- google-cloud-platform - GCP 政策继承理解冲突
- unix - 如何循环播放来自 Spotify 的曲目的无休止请求?
- excel - F4 on Excel ranges, is it possible?
- html - 表单提交按钮在 MacBook 和 iphone 上不起作用
- bash - 如何比较两个文件以允许不匹配的bash
- r - For循环不将结果存储在专用数据框列中