flutter - Flutter PageView,我可以动画从列表中删除项目吗?
问题描述
我对颤动很陌生,我正在尝试在 PageView 上做一些动画。准确地说,我想动画删除一个项目。
我尝试了几种方法来制作动画,除了解决方案之外,你们解决此类问题的方式也将有助于我的颤振技巧。
到目前为止我已经尝试过:
- 动画填充和不透明度
- 问题在于,当我在 onLongPress 的 setState 中设置填充时,它会重建小部件,并使用活动或非活动 CardPadding 再次覆盖填充(我认为)
- 动画宽度和高度
- 我似乎无法让这两个值都起作用
- 在 PageViewController 上动画 viewportFraction
- 不知道该怎么做,以及是否可以仅针对特定的“页面”执行此操作
下面是我迄今为止编写的(精简的)代码。
class Main extends StatefulWidget {
@override
_MainState createState() => _MainState();
}
class _MainState extends State<Main> {
int activeCard = 0;
EdgeInsets inActiveCardPadding = EdgeInsets.symmetric(vertical: 120.0, horizontal: 20.0);
EdgeInsets activeCardPadding = EdgeInsets.symmetric(vertical: 105.0, horizontal: 10.0);
PageController pageController = PageController(
initialPage: 0,
viewportFraction: 0.8,
);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: <Widget>[
PageView.builder(
itemCount: PlantCareApp.plants.length,
controller: pageController,
onPageChanged: (activeCardIndex) {
setState(() {
this.activeCard = activeCardIndex;
});
},
itemBuilder: (context, cardIndex) {
return AnimatedContainer(
padding: (activeCard == cardIndex) ? activeCardPadding : inActiveCardPadding;,
duration: Duration(milliseconds: 250),
child: PlantCard(
PlantCareApp.plants[cardIndex],
onTap: () {
Navigator.pushNamed(context, PlantDetailScreen.route, arguments: PlantCareApp.plants[cardIndex]);
},
onLongPress: () {
setState(() {
//
// ANIMATE OR TRIGGER ANIMATION HERE
//
// do the actual removing
/*
PlantCareApp.plants[cardIndex].remove(); // remove from db
PlantCareApp.plants.removeAt(cardIndex); // remove from List
*/
});
//PlantCareApp.plants[cardIndex].remove();
},
),
);
},
),
],
),
),
);
}
}
任何帮助将不胜感激!你们将如何解决这样的问题,或者您将如何解决这个特定的用例。
我想实际上动画 viewportFraction 将是最好的,因为相邻的“页面”也会相互移动?
谢谢!
解决方案
我不确定这是否是您正在寻找的东西,但这里有。
一种方法是简单地使用 Flutter 中提供的 Widget。其中两个将帮助您:AnimatedList和Dismissible。
现在,您可以执行以下操作:
// define somewhere
final _animatedListGK = GlobalKey<AnimatedListState>();
// put in a function somewhere
return AnimatedList(
key: _animatedListGK,
padding: const EdgeInsets.all(0),
initialItemCount: PlantCareApp.plants.length,
itemBuilder: (context, index, animation) {
return FadeTransition(
opacity: animation,
child: _buildDismissibleRow(context, index, PlantCareApp.plants[index])
);
}
);
注意:您不必使用_animatedListGK
全局密钥本身,这取决于您是否可以使用AnimatedList.of(context)
。虽然这是更简单的方法。
这_animatedListGK
只是一个提供对 的访问的全局键AnimatedList
,因此您可以使用动画执行插入/删除。
您的可忽略行可能类似于:
Widget _buildDismissibleRow(BuildContext context, int index, PlantModel plantModel) {
return Dismissible(
key: ValueKey<String>(plantModel.someKey),
direction: DismissDirection.startToEnd,
background: Container(color: Colors.red),
onDismissed: (direction) {
// You could use:
// AnimatedList.of(context)
_animatedListGK.currentState.removeItem(
index,
(context, animation) => Container(),
duration: Duration.zero
);
},
child: _buildContent(context, index, plantModel)
);
}
您也可以在没有可解雇行的情况下执行此操作,甚至可以在可解雇行的子项内执行此操作(_buildContent()
例如)。类似于:
// You could use:
// AnimatedList.of(context)
_animatedListGK.currentState.removeItem(
index,
(context, animation) {
return FadeTransition(
opacity: CurvedAnimation(parent: animation, curve: Interval(0.5, 1.0)),
child: SizeTransition(
sizeFactor: CurvedAnimation(parent: animation, curve: Interval(0.0, 1.0)),
child: _builContent(context, index, plantModel)
)
);
},
duration: const Duration(milliseconds: 300)
);
请注意SizeTransition
简单地通过调用“调用自身” _builContent(context, index, plantModel)
?这就是您可以为行本身设置动画的方式(不存在)。
请务必观看上述文档页面中的视频!它们将有助于理解某些结构。
推荐阅读
- javascript - Javascript 查询选择器
- php - 如何通过 PHPMailer 发送可填写的 pdf(用 pdftk 填充)?
- pivot-table - 如何在 Oracle Sql 开发人员中使用 Pivot 查询将变量添加到自动拾取列行名并将其转换为新的列标题
- php - cURL PHP中的HTTPS不需要SSL证书吗?
- python - 如何将 xml 解析为具有兄弟元素的表?
- google-api - 在 Google Developer's Console 中,当我尝试编辑或创建 OAuth 同意屏幕时,我不断收到此错误
- android - 仅使用风味的 analitic-kit 的正确方法?,将 json 文件放入风味文件夹 HAPlugin 找不到文件
- apache-spark-sql - 如何在不分组的情况下每 5 分钟获取最近 1 小时的数据?
- c# - Entity Framework Core 项目迁移失败,调试配置文件不存在
- python - 在 y 增加后做 x