检测可滚动小部件是否手动或以编程方式滚动

问题描述 投票:0回答:2

有没有办法检测是否滚动

  1. PageView
    (
    PageController
    ) 或
  2. Scrollable
    小部件 (
    ScrollController
    )

由用户手动完成,或使用控制器对象上的

jumpTo()
animateTo()
以编程方式完成。

将可滚动小部件包装在

NotificationListener
中也不会给我们任何此类回调或标志。

我找到了一个解决方案,但我发现它有点老套,想知道是否有更好的解决方案:

我的解决方案:

Scrollable
小部件包装在
GestureDetector
小部件中,并使用
onTapUp
onTapDown
回调函数并设置标志 (
isScrollManual
) 来检查滚动是手动还是编程。

这是代码:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyPageControllers(),
        ),
      ),
    );
  }
}

class MyPageControllers extends StatefulWidget {
  @override
  _MyPageControllersState createState() => _MyPageControllersState();
}

class _MyPageControllersState extends State<MyPageControllers> {

  PageController _controller1;
  bool isScrollManual = false;

  @override
  void initState() {
    super.initState();
    _controller1 = PageController();

    _controller1.addListener(() {
      if(isScrollManual){
        /// Manual Scroll
      }else{
        /// Programmatic scroll
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: GestureDetector(
        onTapDown: (tapDownDetails){
          isScrollManual = true;
          setState(() {});
        },
        onTapUp: (tapUpDetails){
          isScrollManual = false;
          setState(() {});
        },
        child: PageView.builder(
          controller: _controller1,
          itemBuilder: _itemBuilder,
        ),
      ),
    );
  }

  Widget _itemBuilder(BuildContext context, int index) =>
      Container(
        color: Colors.primaries[index % Colors.primaries.length],
        child: Center(
          child: Text(
            index.toString(),
            style: TextStyle(color: Colors.white, fontSize: 60),
          ),
        ),
      );
}
flutter dart flutter-layout flutter-animation
2个回答
1
投票

我找到的唯一可行的解决方案是将

Scrollable
小部件包装在
GestureDetector
小部件中,并使用
onTapUp
onTapDown
回调函数并设置一个标志(
isScrollManual
)来检查滚动是否是手动的或以编程方式。

这是代码:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyPageControllers(),
        ),
      ),
    );
  }
}

class MyPageControllers extends StatefulWidget {
  @override
  _MyPageControllersState createState() => _MyPageControllersState();
}

class _MyPageControllersState extends State<MyPageControllers> {

  PageController _controller1;
  bool isScrollManual = false;

  @override
  void initState() {
    super.initState();
    _controller1 = PageController();

    _controller1.addListener(() {
      if(isScrollManual){
        /// Manual Scroll
      }else{
        /// Programmatic scroll
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: GestureDetector(
        onTapDown: (tapDownDetails){
          isScrollManual = true;
          setState(() {});
        },
        onTapUp: (tapUpDetails){
          isScrollManual = false;
          setState(() {});
        },
        child: PageView.builder(
          controller: _controller1,
          itemBuilder: _itemBuilder,
        ),
      ),
    );
  }

  Widget _itemBuilder(BuildContext context, int index) =>
      Container(
        color: Colors.primaries[index % Colors.primaries.length],
        child: Center(
          child: Text(
            index.toString(),
            style: TextStyle(color: Colors.white, fontSize: 60),
          ),
        ),
      );
}

0
投票

您可以包裹在

Listener
中,并使用
onPointerUp
功能,您可以检测用户何时刚刚完成与可滚动小部件的交互:

Listener(
    onPointerUp: (pointerUpEvent) {
        //interaction finished
    },
    child: PageView(),
),
© www.soinside.com 2019 - 2024. All rights reserved.