iOS flutter 中的搜索栏动画
iOS search bar animation in flutter
我想在用户点击时在搜索栏中添加动画(就像 whatsApp 或 telegram 中的动画 [仅 iOS])
here is the animation
我使用了 Hero 小部件来执行此操作,但该小部件无法正常工作,我不知道为什么。这是我的代码
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
//some widgets above the search bar
Hero(
tag: 'search',
child: Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),
),
//some more widgets here inside the column
])
这是第一页的部分代码,另一页只是搜索栏。
这是几乎相同的另一页
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Hero(
tag: 'search',
child: Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),
),
),
);
}
请问还有其他方法吗?
编辑:它现在可以与 Hero 小部件一起正常工作,但它并没有像上面的 gif 那样显示确切的行为。应该怎么做,如果有人有其他方法可以实现,也可以回答。
Hero 在不同页面之间移动时使用(在上面的动画中)我们没有导航到任何其他页面,因此,删除 Hero
小部件
这可以通过 Transform.translate
结合 Flutter 中的 Opacity()
小部件来完成。
用Transform.translate
包裹相应的小部件创建一个Tween Animation并在Offset(dx, dy)
的帮助下改变它的高度(在这种情况下dx将为0而dy将为变化的高度),负数dy 值将使小部件向上移动。也用 Opacity()
包裹起来,随着高度的变化而变化。
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Transform.translate(
offset: Offset(0, animatedHeightFromTweenAnimation)
child: Opacity(
opacity: animatedHeightFromTweenAnimation/maxHeightValue;
child: anyWidget()
)
)
Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),//container
RaisedButton(
onPressed: () => controller.forward(), //here controller is animation controller
//the above line will start the animation
child: Text("press it"),
),
//some more widgets here inside the column
])
我想在用户点击时在搜索栏中添加动画(就像 whatsApp 或 telegram 中的动画 [仅 iOS])
here is the animation
我使用了 Hero 小部件来执行此操作,但该小部件无法正常工作,我不知道为什么。这是我的代码
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
//some widgets above the search bar
Hero(
tag: 'search',
child: Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),
),
//some more widgets here inside the column
])
这是第一页的部分代码,另一页只是搜索栏。 这是几乎相同的另一页
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Hero(
tag: 'search',
child: Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),
),
),
);
}
请问还有其他方法吗?
编辑:它现在可以与 Hero 小部件一起正常工作,但它并没有像上面的 gif 那样显示确切的行为。应该怎么做,如果有人有其他方法可以实现,也可以回答。
Hero 在不同页面之间移动时使用(在上面的动画中)我们没有导航到任何其他页面,因此,删除 Hero
小部件
这可以通过 Transform.translate
结合 Flutter 中的 Opacity()
小部件来完成。
用Transform.translate
包裹相应的小部件创建一个Tween Animation并在Offset(dx, dy)
的帮助下改变它的高度(在这种情况下dx将为0而dy将为变化的高度),负数dy 值将使小部件向上移动。也用 Opacity()
包裹起来,随着高度的变化而变化。
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Transform.translate(
offset: Offset(0, animatedHeightFromTweenAnimation)
child: Opacity(
opacity: animatedHeightFromTweenAnimation/maxHeightValue;
child: anyWidget()
)
)
Container(
height: 38,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
hintStyle: TextStyle(fontSize: 16),
hintText: "Search here",
prefixIcon: Icon(Icons.search),
border: InputBorder.none,
),
),
),//container
RaisedButton(
onPressed: () => controller.forward(), //here controller is animation controller
//the above line will start the animation
child: Text("press it"),
),
//some more widgets here inside the column
])