Flutter教程-自定义无限滚动轮播器infinity_slider-增加多轮播嵌套联动功能(二)

原文链接: https://juejin.im/post/5d6c973ae51d45620064bb92

简介

上篇文章我们通过组合PageView方式,实现一个自定义的infinity_slider小部件,这篇文章我们实现多个infinity_slider嵌套实现滑动互联的效果

目标

  • 多个infinity_slider嵌套实现滑动互联的效果

完整代码

  • pub: https://pub.dev/packages/infinity_slider
  • github: https://github.com/herghost000/flutter_infinity_slider

思路

  1. 通过widget树找到父infinity_slider控件
  2. 使用NotificationListener监听当前infinity_slider控件滚动
  3. 使用父infinity_slider控件的_pageController移动父infinity_slider控件的位置
  4. 禁用当前infinity_slider控件在父infinity_slider控件未抵达边缘时产生的光晕效果

步骤

1) 找到父infinity_slider控件

InfinitySlider类中添加此代码

static InfinitySliderState of(BuildContext context) {
    return context.ancestorStateOfType(TypeMatcher());
}

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;
}

你可能感兴趣的:(Flutter)