【问题标题】:Flutter detect user scroll with ScrollControllerFlutter 使用 ScrollController 检测用户滚动
【发布时间】:2020-03-10 17:27:20
【问题描述】:

项目

嗨,我正试图用我的自定义控制器和监听器构建一个简单的列表。 这是代码

class Test2 extends StatefulWidget {
  @override
  _Test2State createState() => _Test2State();
}

class _Test2State extends State<Test2> {
  ScrollController scrollController = ScrollController();

  @override
  void initState() {
    scrollController.addListener((){
      print('controller called');
    });
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: ListView.builder(
          controller: scrollController,
      itemCount: 8,
      itemBuilder: (context, index) {
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Container(
            color: Colors.white,
            height: 50,
          ),
        );
      },
    ));
  }
}

问题

我的代码按预期工作,但我试图检测用户的滑动,即使没有任何东西可以滑动。到目前为止,如果在调用用户滑动滚动侦听器时列表溢出屏幕,但是当项目列表短于屏幕大小时,则不会发生这种情况。 我怎样才能强迫听众总是听?

【问题讨论】:

  • 尝试改用NotificationListener
  • 即使列表太短而无法滚动,是否也会检测到滑动?

标签: flutter


【解决方案1】:

也许这段代码可以帮助你。

在 NotificationListener 上包装脚手架可以监听所有事件,即使 itemCount 为零

别忘了提供一个AlwaysScrollableScrollPhysics物理对象

import 'dart:math' as math;

import 'package:flutter/material.dart';

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  @override
  Widget build(BuildContext context) {
    final ScrollController scrollController = ScrollController();

    return NotificationListener(
      child: Scaffold(
        body: ListView.builder(
          controller: scrollController,
          physics: const AlwaysScrollableScrollPhysics(),
          itemCount: 0,
          itemBuilder: (context, index) {
            return Container(
              color: Colors.black,
              height: 50,
            );
          },
        ),
      ),
      onNotification: (notificationInfo) {
        if (notificationInfo is ScrollStartNotification) {
          print("scroll");
          print("detail:"+notificationInfo.dragDetails.toString());
          /// your code
        }
        return true;
      },
    );
  }
}

【讨论】:

  • 由于这个未解决的问题,这现在不起作用:github.com/flutter/flutter/issues/44732
  • 如果我在这里放置一个像滚动这样的函数来索引,我会得到多个错误。有没有办法确定用户是否向右滚动然后跳转到下一个右侧索引,如果用户向左滚动则转到上一个索引?
【解决方案2】:

您必须将自定义滚动侦听器传递给函数:

scrollController.addListener(_scrollListener);

完成:

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

以及您的自定义滚动监听器方法:

_scrollListener() {
    if (_controller.offset >= _controller.position.maxScrollExtent &&
        !_controller.position.outOfRange) {
      setState(() {
        message = "reach the bottom";
      });
    }
    if (_controller.offset <= _controller.position.minScrollExtent &&
        !_controller.position.outOfRange) {
      setState(() {
        message = "reach the top";
      });
    }
  }

来源:https://medium.com/@diegoveloper/flutter-lets-know-the-scrollcontroller-and-scrollnotification-652b2685a4ac

【讨论】:

  • 问题是如果没有实际滚动,scrollListener 不会触发。我的列表是动态构建的,我不知道列表是否会溢出屏幕高度
  • 如果列表视图不可滚动,你想做什么?
  • 我想触发一个设置状态,该状态将折叠该部分
  • 那你为什么不使用Wrap( children: &lt;Widget&gt;[]) ) 方法或列呢? Column( mainAxisSize: MainAxisSize.max, children: &lt;Widget&gt;[], );
  • 因为我不知道要构建多少个列表视图元素。他们是动态的。在示例中,为了简单起见,我硬编码了元素的数量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 2019-02-28
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多