如何获取 NestedScrollView 的滚动方向

joh*_*ris 8 dart flutter

我正在尝试获取 NestedScrollView 的滚动方向(向上/向下),以便我的小部件之一可以做出相应的反应。

我已经使用了NotificationListener小部件并尝试打印它返回的axisDirection,但当我向两个方向滚动时它只返回“向下”。显然,这就是它应该的行为方式,但是,Flutter 中似乎没有任何方法可以知道如何获取滚动方向。有没有办法获取滚动方向,无论是 AxisDirection 还是 bool ?

@override
  Widget build(BuildContext context) {

    return Container(
      color: Colors.black,
      child: SafeArea(
        child: Scaffold(
          backgroundColor: Color.fromARGB(255, 22, 22, 22),
          body: NotificationListener<ScrollStartNotification>(
            onNotification: (ScrollNotification scrollInfo) {


              print("scrollInfo up ===== ${scrollInfo.metrics.axisDirection}");


            },
            child: NotificationListener<ScrollStartNotification>(
              onNotification: (ScrollNotification scrollInfo) {
                if (scrollInfo.metrics.axisDirection == AxisDirection.down) {
                  print(
                      "scrollViewColtroller down == ${scrollViewColtroller.position.axisDirection}");
                }
              },
              child: NestedScrollView(
                controller: scrollViewColtroller,
                headerSliverBuilder:
                    (BuildContext context, bool boxIsScrolled) {
                  return <Widget>[
                    SliverAppBar(
                      floating: true,
                      snap: true,
                      pinned: false,
                      elevation: 10,
                    )
                  ];
                },
                body: Container(
                  padding: EdgeInsets.all(0.0),
                  child: Center(
                    child: Column(
                      children: <Widget>[
                        SizedBox(
                          height: 1,
                        ),
                        _feedPosts(context)
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

这就是它打印的内容。

scrollViewColtroller up ===== AxisDirection.down
scrollInfo up == AxisDirection.down
scrollViewColtroller up ===== AxisDirection.down
scrollInfo up == AxisDirection.down
Run Code Online (Sandbox Code Playgroud)

Maz*_*him 8

AxisDirection不用于检测滚动方向,它用于返回结构Scrollable,在您的情况下默认情况下NestedScrollView具有scrollDirection = Axis.Vertical,这使得它从顶部开始,并且它的AxisDirection = AxisDirection.down. 因此,当您尝试向上和向下滚动时,您会收到相同的结果,因为列表结构不会因滚动事件而改变。

要实现您想要的效果,您可以将当前位置与默认位置 ( 0.0) 进行比较,如果ScrollNotification.metrics.pixels大于前一个位置,则列表向上滚动(如果是水平位置则向左滚动),如果小于则向下滚动。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  final appTitle = 'Scroll Direction Detection';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>{

  double position = 0.0 ;

  double sensitivityFactor = 20.0 ;

  @override
  Widget build(BuildContext context) {

    return Container(
      child: SafeArea(
        child: Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: NotificationListener<ScrollNotification>(
            onNotification: (ScrollNotification scrollInfo) {
              if(scrollInfo.metrics.pixels - position >= sensitivityFactor){
                print('Axis Scroll Direction : Up');
                position = scrollInfo.metrics.pixels ;
              }
              if(position - scrollInfo.metrics.pixels  >= sensitivityFactor){
                print('Axis Scroll Direction : Down');
                position = scrollInfo.metrics.pixels ;
              }

            },
            child: ListView.builder(
              itemCount: 100,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text('$index'),
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


anm*_*ail 7

您可以通过以下方式获取方向:scrollViewColtroller.position

首先添加-import 'package:flutter/rendering.dart';

代码:

    @override
  Widget build(BuildContext context) {
    return Scaffold(
      //  backgroundColor: Color.fromARGB(255, 22, 22, 22),
      body: NotificationListener<ScrollUpdateNotification>(
        onNotification: (ScrollNotification scrollInfo) {
          if (scrollViewColtroller.position.userScrollDirection ==
              ScrollDirection.reverse) {
            print('User is going down');
            setState(() {
              message = 'going down';
            });
          } else {
            if (scrollViewColtroller.position.userScrollDirection ==
                ScrollDirection.forward) {
              print('User is going up');
              setState(() {
                message = 'going up';
              });
            }
          }
        },
        child: NestedScrollView(
          controller: scrollViewColtroller,
          headerSliverBuilder: (BuildContext context, bool boxIsScrolled) {
            return <Widget>[
              SliverAppBar(
                floating: true,
                snap: true,
                pinned: false,
                elevation: 10,
              )
            ];
          },
          body: Container(
            padding: EdgeInsets.all(0.0),
            child: Column(
              children: <Widget>[
                Container(
                  height: 150.0,
                  color: Colors.green,
                  child: Align(
                    alignment: Alignment.bottomCenter,
                    child: Text(
                      message,
                      style: TextStyle(color: Colors.white, fontSize: 25.0),
                    ),
                  ),
                ),
                Expanded(
                    child: ListView(
                  children: List.generate(100, (i) {
                    return Text(i.toString());
                  }).toList(),
                ))
              ],
            ),
          ),
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

输出: 在此输入图像描述