内容区滑动至最右侧继续左滑,跳转至某某页面flutter实现(原创)

418 阅读1分钟

需求介绍

某年某月某天,有一个交互,这个交互需要内容区滑动至最右侧继续左滑,跳转至某某页面

image.png

调研遍全网没看到(可能是我没找到)实现这个需求的文章,这边自己开发了一个让大家用一用,也记录一下

先来个流程图

1. 监听滚动事件,是否滚动到底部

2. 滚动到底部记录,将isatend标记为true,相反记录为false

    if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent && _isAtEnd == false) {
      setState(() {
        _isAtEnd = true;
      });
    } else if(_scrollController.position.pixels < _scrollController.position.maxScrollExtent && _isAtEnd == true) {
      setState(() {
        _isAtEnd = false;
      });
    }

3. 将listview的physics从ClampingScrollPhysics (滚动边缘后会立即停止) 变头BouncingScrollPhysics (允许用户在到达边缘后继续滚动一段距离)模拟继续滚动的拖拽动画

ListView.builder(
          physics:_isAtEnd ? BouncingScrollPhysics() : ClampingScrollPhysics(),
          controller: _scrollController,
          scrollDirection: Axis.horizontal,
          itemCount: 20,
          itemBuilder: (context, index) {
            return Container(
              width: 100,
              color: Colors.orange[(index % 9 + 1) * 100],
              child: Center(
                child: Text(_isAtEnd? '右滑跳转': '右滑'),
              ),
            );
          },
        )

4. 判断是否到达底部并继续滚动,将 overflow标记为true

    // 检测是否到达底部并且继续滚动
    if (offset >= maxScrollExtent) {
      double overscroll = offset - maxScrollExtent;
      if (overscroll > 0) {
        _onReachBottomOverscroll(overscroll);
      }
    }
    void _onReachBottomOverscroll(double overscroll) {
    // 自定义事件处理,例如触发某些操作
    print('Reached bottom and overscrolled by: $overscroll');
    if(_overflow == false){
      _overflow = true;
    }

5. 在滚动监听事件里判断如果滚动到底部目overflow为true的话执行跳转函数,并将overflow标记为false

 if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
      if (_overflow) {
        print('我将跳转');
        _overflow = false;
      }
    }

呈现效果

是个视频 上传不了就截个图吧

image.png

代码

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ScrollController _scrollController = ScrollController();
  bool _isAtEnd = false;
  bool _overflow = true;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_scrollListener);
  }


    void _scrollListener() {
    // 获取当前滚动位置
    double offset = _scrollController.offset;
    double maxScrollExtent = _scrollController.position.maxScrollExtent;
    double minScrollExtent = _scrollController.position.minScrollExtent;
    if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
      if (_overflow) {
        print('我将跳转');
        _overflow = false;
      }
    }
    if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent && _isAtEnd == false) {
      setState(() {
        _isAtEnd = true;
      });
    } else if(_scrollController.position.pixels < _scrollController.position.maxScrollExtent && _isAtEnd == true) {
      setState(() {
        _isAtEnd = false;
      });
    }
    // 检测是否到达底部并且继续滚动
    if (offset >= maxScrollExtent) {
      double overscroll = offset - maxScrollExtent;
      if (overscroll > 0) {
        _onReachBottomOverscroll(overscroll);
      }
    }
  }
    void _onReachBottomOverscroll(double overscroll) {
    // 自定义事件处理,例如触发某些操作
    print('Reached bottom and overscrolled by: $overscroll');
    if(_overflow == false){
      _overflow = true;
    }
    // 可以在这里执行其他操作,比如加载更多数据或展示提示
  }


  @override
  Widget build(BuildContext context) {
    return  ListView.builder(
          physics:_isAtEnd ? BouncingScrollPhysics() : ClampingScrollPhysics(),
          controller: _scrollController,
          scrollDirection: Axis.horizontal,
          itemCount: 20,
          itemBuilder: (context, index) {
            return Container(
              width: 100,
              color: Colors.orange[(index % 9 + 1) * 100],
              child: Center(
                child: Text(_isAtEnd? '右滑跳转': '右滑'),
              ),
            );
          },
        );
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }
}