我有一个PageView,我想以编程方式滚动pageView,所以我有两个选择:
animateToPage
jumpToPage
现在,我需要平滑的过渡效果,因此我必须使用第一个api。但是,我有一个问题:
animateToPage
将加载当我从首页滚动到最后一页时不需要显示的中间页面(jumpToPage没有这个问题,但是我需要动画)。如何避免呢?
最佳答案
我们可以通过实现
在此示例中,我使用了固定的 PageView子级计数,即8。
演示版
比较
如CopsOnRoad建议的那样,此按钮将触发滚动动画至最后一页(在本例中为第8页)。首先,我们
jumpToPage(6),然后设置animateToPage(7,..)。
这种方法可以使用,但不利的是,用户会注意到当前页面突然更改为第7页。
与第一种方法不同,此按钮将避免不必要地显示第7页
语法说明
这是的主要功能
void flashToEight() async {
int pageCurrent = pageController.page.round();
int pageTarget = 7;
if (pageCurrent == pageTarget){
return;
}
swapChildren(pageCurrent, pageTarget); // Step # 1
await quickJump(pageCurrent, pageTarget); // Step # 2 and # 3
WidgetsBinding.instance.addPostFrameCallback(refreshChildren); // Step # 4
}
详细外观
// Step # 1
void swapChildren(int pageCurrent, int pageTarget) {
List<Widget> newVisiblePageViews = [];
newVisiblePageViews.addAll(pageViews);
if (pageTarget > pageCurrent) {
newVisiblePageViews[pageCurrent + 1] = visiblePageViews[pageTarget];
} else if (pageTarget < pageCurrent) {
newVisiblePageViews[pageCurrent - 1] = visiblePageViews[pageTarget];
}
setState(() {
visiblePageViews = newVisiblePageViews;
});
}
// Step # 2 and # 3
Future quickJump(int pageCurrent, int pageTarget) async {
int quickJumpTarget;
if (pageTarget > pageCurrent) {
quickJumpTarget = pageCurrent + 1;
} else if (pageTarget < pageCurrent) {
quickJumpTarget = pageCurrent - 1;
}
await pageController.animateToPage(
quickJumpTarget,
curve: Curves.easeIn,
duration: Duration(seconds: 1),
);
pageController.jumpToPage(pageTarget);
}
// Step # 4
List<Widget> createPageContents() {
return <Widget>[
PageContent(1),
PageContent(2),
PageContent(3),
PageContent(4),
PageContent(5),
PageContent(6),
PageContent(7),
PageContent(8),
];
}
void refreshChildren(Duration duration) {
setState(() {
visiblePageViews = createPageContents();
});
}
完整的工作示例存储库
您可以查看完整的源代码并在本地构建。 Github