简体   繁体   English

当子 ListView 达到滚动限制时让 PageView 页面滚动 - 嵌套滚动?

[英]Make PageView page scroll when child ListView reaches scroll limit - nested scroll?

Nested scrolling?嵌套滚动?

I have three vertical pages in a PageView that I want to be able to flip between.我希望能够在PageView之间切换三个垂直页面。 The pages consists of scrollable ListView s.这些页面由可滚动的ListView组成。

When a page is in focus the displayed list should be vertically scrollable, but when the list is scrolled to either end I want the pageView scrolling to take over the scroll behaviour and handle the page flipping to next page (like a web page with scrollable elements).当页面处于焦点时,显示的列表应该是垂直可滚动的,但是当列表滚动到任一端时,我希望 pageView 滚动接管滚动行为并处理页面翻转到下一页(就像带有可滚动元素的网页一样)。

Example with scrolling lists below.下面的滚动列表示例。 If the list scrolling is disabled the page flipping works.如果禁用列表滚动,则翻页有效。 How can I make both work?我怎样才能使两者都工作?

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: VerticalPageView(),
    );
  }
}

class VerticalPageView extends StatelessWidget {
  VerticalPageView({Key key}) : super(key: key);

  final PageController pageController = PageController();
  final ScrollController scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: PageView(
          controller: pageController,
          pageSnapping: true,
          scrollDirection: Axis.vertical,
          children: <Widget>[
            Container(
              color: Colors.pinkAccent,
              child: ListView.builder(
                controller: scrollController,
                itemCount: 100,
                physics: ClampingScrollPhysics(),
                itemBuilder: (context, index) {
                  return Text('page 0 item $index');
                },
              ),
            ),
            Container(
              color: Colors.lightBlue,
              child: ListView.builder(
                controller: scrollController,
                itemCount: 100,
                physics: ClampingScrollPhysics(),
                itemBuilder: (context, index) {
                  return Text('page 1 item $index');
                },
              ),
            ),
            Container(
              color: Colors.lightGreen,
              child: ListView.builder(
                controller: scrollController,
                itemCount: 100,
                physics: ClampingScrollPhysics(),
                itemBuilder: (context, index) {
                  return Text('page 2 item $index');
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I think what you are trying to achieve is not impossible but needs a lot of study and care.我认为你想要达到的目标并非不可能,但需要大量的学习和关心。

I have been trying to use several NotificationListener<ScrollNotification> 's to adapt the reaction depending on the position of the scroll but did not get anywhere.我一直在尝试使用几个NotificationListener<ScrollNotification>来根据滚动的位置调整反应,但没有得到任何结果。

Give a look to the Animation sample home.dart file in the Gallery App.查看图库应用程序中的动画示例home.dart文件。 It is full of insight in this regard.它在这方面充满了洞察力。

The problem with this approach is basically what you say.这种方法的问题基本上就是你所说的。 When you disable programmatically the scrolling when reaching the end of the list to enable page scrolling, then you can switch to the other page but can't scroll the list in the other direction any more.当您以编程方式禁用到达列表末尾时的滚动以启用页面滚动时,您可以切换到另一个页面,但不能再向另一个方向滚动列表。

So, either you scroll the list or you scroll the pages, but not both.因此,要么滚动列表,要么滚动页面,但不能同时滚动。

Maybe you could add a GestureDetector() above everything and check on every drag update what is your situation below to configure accordingly the different scrollers.也许您可以在所有内容之上添加一个GestureDetector()并检查每次拖动更新您的情况是什么,以相应地配置不同的滚动条。

Anyway, in case it is helpful to you I let you here an alternate solution using a CustomScrollView and SliverList 's.无论如何,如果它对你有帮助,我让你在这里使用CustomScrollViewSliverList的替代解决方案。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: VerticalPageView(),
    );
  }
}

class VerticalPageView extends StatelessWidget {
  final ScrollController _scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        controller: _scrollController,
        slivers: <Widget>[
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  color: Colors.pinkAccent,
                  child: Text('page 0 item $index'),
                );
              },
              childCount: 100,
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  color: Colors.lightBlue,
                  child: Text('page 1 item $index'),
                );
              },
              childCount: 100,
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  color: Colors.lightGreen,
                  child: Text('page 2 item $index'),
                );
              },
              childCount: 100,
            ),
          ),
        ],
      ),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM