簡介
上篇文章我們通過組合PageView方式,實現一個自定義的infinity_slider小部件,這篇文章我們實現多個
infinity_slider
巢狀實現滑動互聯的效果
目標
- 多個
infinity_slider
巢狀實現滑動互聯的效果
完整程式碼
- pub: pub.dev/packages/in…
- github: github.com/herghost000…
思路
- 通過widget樹找到父
infinity_slider
控制元件 - 使用
NotificationListener
監聽當前infinity_slider
控制元件滾動 - 使用父
infinity_slider
控制元件的_pageController
移動父infinity_slider
控制元件的位置 - 禁用當前
infinity_slider
控制元件在父infinity_slider
控制元件未抵達邊緣時產生的光暈效果
步驟
1) 找到父infinity_slider
控制元件
在InfinitySlider
類中新增此程式碼
static InfinitySliderState of(BuildContext context) {
return context.ancestorStateOfType(TypeMatcher<InfinitySliderState>());
}
複製程式碼
在initState
中初始化下方程式碼
InfinitySliderState _ancestor;
@override
void initState() {
_linkAncestorIfNeeded();
}
void _linkAncestorIfNeeded() {
_ancestor = InfinitySlider.of(context);
}
複製程式碼
2) 監聽當前infinity_slider
控制元件滾動
@override
Widget build(BuildContext context) {
return NotificationListener(
onNotification: _handleScrollNotification,
child: PageView.builder(
......
)
);
}
void _handleScrollNotification(ScrollNotification notification) {
}
複製程式碼
3) 控制父infinity_slider
控制元件滾動
bool _handleScrollNotification(ScrollNotification notification) {
if (notification is OverscrollNotification && _ancestor != null) {
if (_canLinkWithAncestorScroll(notification.overscroll < 0)) {
_ancestor._pageController.position
.moveTo(_ancestor._pageController.offset + notification.overscroll);
}
}
}
bool _canLinkWithAncestorScroll(bool onLeftEdge) {
if (_ancestor == null) return false;
return (onLeftEdge &&
_ancestor._pageController.offset !=
_ancestor._pageController.position.minScrollExtent) ||
((!onLeftEdge &&
_ancestor._pageController.offset !=
_ancestor._pageController.position.maxScrollExtent));
}
複製程式碼
4) 禁用infinity_slider
控制元件在與父infinity_slider
控制元件聯動產生的光暈
@override
Widget build(BuildContext context) {
return NotificationListener(
onNotification: _handleScrollNotification,
child: NotificationListener(
onNotification: _handleGlowNotification,
child: PageView.builder(
......
)
)
);
)
bool _handleGlowNotification(OverscrollIndicatorNotification notification) {
if (notification.depth == 0 &&
_canLinkWithAncestorScroll(notification.leading)) {
notification.disallowGlow();
return true;
}
return false;
}
複製程式碼