skip to Main Content

I meet problem with the ListView. When i scroll listview to top I will disable Scroll. But when I scroll down again, the listview not scroll down. I want when I scroll up it will able scroll down again. Pls help me !

class PageTwo extends StatefulWidget {
  const PageTwo({Key? key}) : super(key: key);

  @override
  State<PageTwo> createState() => _PageTwoState();
}

class _PageTwoState extends State<PageTwo> {
  ScrollController scrollController = ScrollController();
  ScrollPhysics scrollPhysics = const BouncingScrollPhysics();

  scrollControllerListener() {
    scrollController.addListener(() {
      if (scrollController.position.pixels <= 0) {
        setState(() {
          scrollPhysics = const NeverScrollableScrollPhysics();
        });
      }
    });
  }

  @override
  void initState() {
    scrollControllerListener();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onLongPress: () {
        setState(() {
          scrollPhysics = const BouncingScrollPhysics();
        });
      },
      onVerticalDragDown: (details) {
        setState(() {
          scrollPhysics = const NeverScrollableScrollPhysics();
        });
      },
      child: ListView.builder(
        controller: scrollController,
        scrollDirection: Axis.vertical,
        physics: scrollPhysics,
        itemCount: 20,
        itemBuilder: (BuildContext context, int index) {
          return const NewWidget();
        },
      ),
    );
  }
}

Tell me about how to fix.

2

Answers


  1. That’s becuz when u reach the top, you u

    scrollPhysics = const NeverScrollableScrollPhysics();

    This makes your ListView won’t be able to scroll anymore. I don’t know why you want to disable scroll when u reach the top, it seems weird. But if you still want to do that way, I have small trick for you: Use Future.delayed with a few milisecs after assiged scrollPhysics = const NeverScrollableScrollPhysics();. Like this:

    scrollControllerListener() {
        scrollController.addListener(() {
          if (scrollController.position.pixels <= 0) {
            setState(() {
              scrollPhysics = NeverScrollableScrollPhysics();
              Future.delayed(
                Duration(milliseconds: 200),
                () => scrollPhysics = BouncingScrollPhysics(), // YOU MAY NEED TO ADD A setState() HERE
              );
            });
          }
        });
    

    A small advice relates to clean code: write a separated function for adding scroll controller’s listener.

    Login or Signup to reply.
  2. To achieve this, you can use the NotificationListener widget to intercept scroll notifications and dynamically change the NeverScrollableScrollPhysics to BouncingScrollPhysics and vice versa. Here’s how you can modify your code to achieve this behavior

    class _PageTwoState extends State<PageTwo> {
      ScrollController scrollController = ScrollController();
      ScrollPhysics scrollPhysics = BouncingScrollPhysics();
    
      @override
      void initState() {
        super.initState();
        scrollController.addListener(() {
          if (scrollController.position.pixels <= 0) {
            setState(() {
              scrollPhysics = NeverScrollableScrollPhysics();
            });
          } else {
            setState(() {
              scrollPhysics = BouncingScrollPhysics();
            });
          }
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onLongPress: () {
            setState(() {
              scrollPhysics = BouncingScrollPhysics();
            });
          },
          onVerticalDragDown: (details) {
            setState(() {
              scrollPhysics = NeverScrollableScrollPhysics();
            });
          },
          child: NotificationListener<ScrollNotification>(
            onNotification: (scrollNotification) {
              // Handle scroll events here if needed
              return false;
            },
            child: ListView.builder(
              controller: scrollController,
              scrollDirection: Axis.vertical,
              physics: scrollPhysics,
              itemCount: 20,
              itemBuilder: (BuildContext context, int index) {
                return const NewWidget();
              },
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search