如何在 Flutter 中制作手势驱动的动画?
How to make a gesture driven animation in Flutter?
我是 Flutter
的新手,目前,我正在尝试制作一个可滑动的底部面板,它可以为某些文本的不透明度设置动画(暂时)。
这基本上就是我要实现的动画
我通过 找到了这个答案,它创建了一个底部 sheet 并获得了它的位置。
如何根据拖动百分比设置 Text
动画?
根据 Saed Nabil 的回应,我对他的样本做了一些调整,并使用 TextStyle.lerp
根据拖动的位置获得文本样式。
StreamController<double> controller = StreamController.broadcast();
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
const defaultTextStyle = TextStyle(
color: Colors.blue,
fontSize: 15,
);
class _MyWidgetState extends State<MyWidget> {
double position;
TextStyle textStyle = defaultTextStyle;
@override
Widget build(BuildContext context) {
final maxPosition = MediaQuery.of(context).size.height - 300;
return Container(
child: Center(
child: RaisedButton(
child: Text('Show Buttom Sheet'),
onPressed: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return StreamBuilder(
stream: controller.stream,
builder: (context, snapshot) => GestureDetector(
onVerticalDragUpdate: (DragUpdateDetails details) {
position = MediaQuery.of(context).size.height -
details.globalPosition.dy;
double newPosition = position;
if (position.isNegative || position == 0)
Navigator.pop(context);
else {
if (position > maxPosition) {
newPosition = maxPosition;
}
controller.add(newPosition);
}
textStyle = TextStyle.lerp(
defaultTextStyle,
TextStyle(
color: Colors.black,
fontSize: 24,
),
newPosition / maxPosition);
},
behavior: HitTestBehavior.translucent,
child: Container(
color: Colors.white,
height: snapshot.hasData ? snapshot.data : 50.0,
width: double.infinity,
child: Text(
'Reviews',
style: textStyle,
textAlign: TextAlign.center,
),
)),
);
});
}),
),
);
}
}
结果
根据您为模态底部使用的解决方案 sheet,您应该能够隔离根据 sheet 变化的变量。通常这是通过一些小部件提供的 controller
来实现的,或者在 Saed Nabil 的情况下,他将该变量输入自定义变量。
只要您拥有变量,您就应该能够通过类似这样的方式为文本小部件上的不透明度小部件提供简单的数学运算。
假设您的变量从 0、0.1、0.111、0.222.....1。你可以这样做:
double opacity = 1 - controller.position;
Opacity(
opacity: opacity,
child: Text(),
);
我是 Flutter
的新手,目前,我正在尝试制作一个可滑动的底部面板,它可以为某些文本的不透明度设置动画(暂时)。
这基本上就是我要实现的动画
我通过
如何根据拖动百分比设置 Text
动画?
根据 Saed Nabil 的回应,我对他的样本做了一些调整,并使用 TextStyle.lerp
根据拖动的位置获得文本样式。
StreamController<double> controller = StreamController.broadcast();
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
const defaultTextStyle = TextStyle(
color: Colors.blue,
fontSize: 15,
);
class _MyWidgetState extends State<MyWidget> {
double position;
TextStyle textStyle = defaultTextStyle;
@override
Widget build(BuildContext context) {
final maxPosition = MediaQuery.of(context).size.height - 300;
return Container(
child: Center(
child: RaisedButton(
child: Text('Show Buttom Sheet'),
onPressed: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return StreamBuilder(
stream: controller.stream,
builder: (context, snapshot) => GestureDetector(
onVerticalDragUpdate: (DragUpdateDetails details) {
position = MediaQuery.of(context).size.height -
details.globalPosition.dy;
double newPosition = position;
if (position.isNegative || position == 0)
Navigator.pop(context);
else {
if (position > maxPosition) {
newPosition = maxPosition;
}
controller.add(newPosition);
}
textStyle = TextStyle.lerp(
defaultTextStyle,
TextStyle(
color: Colors.black,
fontSize: 24,
),
newPosition / maxPosition);
},
behavior: HitTestBehavior.translucent,
child: Container(
color: Colors.white,
height: snapshot.hasData ? snapshot.data : 50.0,
width: double.infinity,
child: Text(
'Reviews',
style: textStyle,
textAlign: TextAlign.center,
),
)),
);
});
}),
),
);
}
}
结果
根据您为模态底部使用的解决方案 sheet,您应该能够隔离根据 sheet 变化的变量。通常这是通过一些小部件提供的 controller
来实现的,或者在 Saed Nabil 的情况下,他将该变量输入自定义变量。
只要您拥有变量,您就应该能够通过类似这样的方式为文本小部件上的不透明度小部件提供简单的数学运算。
假设您的变量从 0、0.1、0.111、0.222.....1。你可以这样做:
double opacity = 1 - controller.position;
Opacity(
opacity: opacity,
child: Text(),
);