Flutter:ListView:当子级ListView到达底部时滚动父级ListView-ClampingScrollPhysics在大小容器中不起作用 [英] Flutter : ListView : Scroll parent ListView when child ListView reach bottom - ClampingScrollPhysics not working in sized container

查看:117
本文介绍了Flutter:ListView:当子级ListView到达底部时滚动父级ListView-ClampingScrollPhysics在大小容器中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Flutter 1.12.13+修补程序.

I'm using Flutter version 1.12.13+hotfix.

我正在寻找一种能够在ListView中滚动的解决方案,当它到达底部时,会自动将滚动线索提供给父级ListView.

I'm looking for a solution to be able to scroll inside a ListView and when reached the bottom, automatically give scroll lead to the parent ListView.

要实现的第一个解决方案是将"physics:ClampingScrollPhysics()"与"shrinkWrap:true"一起使用.所以我将此解决方案应用于除第一个(红色)之外的所有子Listview,因为我需要将其包装在大小合适的Container()中.

The first solution to achieve that is to use "physics: ClampingScrollPhysics()" with "shrinkWrap: true". So I apply this solution to all sub Listview except first one (the red) because I need to wrap it inside a sized Container().

问题来自第一个问题……ClampingScrollPhysics()无法与大小合适的Container()一起使用!

The problem come from the first one... ClampingScrollPhysics() didn't work with sized Container() !

因此,当我滚动红色的Listview并到达其底部时,滚动停止...我需要将手指放在此ListView之外才能再次滚动.

So, when I scroll the red Listview and reach its bottom, scroll stoping... I need to put my finger outside this ListView to be able again to scroll.

@override
  Widget build(BuildContext context) {
    super.build(context);

    print("build MySongs");

    return ListView(
      children: <Widget>[
        Container(
          height: 170,
          margin: EdgeInsets.all(16),
          child: ListView(
            children: <Widget>[
              Container(color: Colors.red, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.red, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.red, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
            ],
          ),
        ),
        Container(
          margin: EdgeInsets.all(16),
          child: ListView(
            physics: ClampingScrollPhysics(),
            shrinkWrap: true,
            children: <Widget>[
              Container(color: Colors.orange, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.orange, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.orange, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
            ],
          ),
        ),
        Container(
          margin: EdgeInsets.all(16),
          child: ListView(
            shrinkWrap: true,
            physics: ClampingScrollPhysics(),
            children: <Widget>[
              Container(color: Colors.blue, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.blue, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.blue, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
            ],
          ),
        ),
        Container(
          margin: EdgeInsets.all(16),
          child: ListView(
            physics: ClampingScrollPhysics(),
            shrinkWrap: true,
            children: <Widget>[
              Container(color: Colors.green, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.green, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
              Container(color: Colors.green, width: 100, height: 100, padding: EdgeInsets.all(8), margin: EdgeInsets.all(8)),
            ],
          ),
        ),
      ],
    );
  }

可能需要在Flutter github问题上发布此问题:/

Maybe in need post this question on Flutter github issue :/

推荐答案

感谢Hamed Hamedi解决方案:)!我认为,基于NotificationListener,我提出了一个更好的解决方案! (由于他,我发现了这种功能).

Thanks for Hamed Hamedi solution :) ! I made a better solution, I think, based on NotificationListener ! (I discovered this functionnality thanks to him).

@override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(8),
      color: Colors.yellow,
      child: ListView.builder(
        controller: controller,
        itemBuilder: (c, i) =>
        i == 10
          ? Container(
          height: 150,
          color: Colors.red,
          child: NotificationListener<OverscrollNotification>(
            onNotification: (OverscrollNotification value) {
              if (value.overscroll < 0 && controller.offset + value.overscroll <= 0) {
                if (controller.offset != 0) controller.jumpTo(0);
                return true;
              }
              if (controller.offset + value.overscroll >= controller.position.maxScrollExtent) {
                if (controller.offset != controller.position.maxScrollExtent) controller.jumpTo(controller.position.maxScrollExtent);
                return true;
              }
              controller.jumpTo(controller.offset + value.overscroll);
              return true;
            },
            child: ListView.builder(
              itemBuilder: (c, ii) => Text('-->' + ii.toString()),
              itemCount: 20,
            ),
          ),
        )
          : Text(i.toString()),
        itemCount: 45,
      ),
    );
  }

解决方案包装在StatelessWidget中:

The solution wrapped into StatelessWidget :

import 'package:flutter/material.dart';

class ScrollParent extends StatelessWidget {
  final ScrollController controller;
  final Widget child;

  ScrollParent({this.controller, this.child});

  @override
  Widget build(BuildContext context) {
    return NotificationListener<OverscrollNotification>(
      onNotification: (OverscrollNotification value) {
        if (value.overscroll < 0 && controller.offset + value.overscroll <= 0) {
          if (controller.offset != 0) controller.jumpTo(0);
          return true;
        }
        if (controller.offset + value.overscroll >= controller.position.maxScrollExtent) {
          if (controller.offset != controller.position.maxScrollExtent) controller.jumpTo(controller.position.maxScrollExtent);
          return true;
        }
        controller.jumpTo(controller.offset + value.overscroll);
        return true;
      },
      child: child,
    );
  }
}

这篇关于Flutter:ListView:当子级ListView到达底部时滚动父级ListView-ClampingScrollPhysics在大小容器中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆