首页 > 解决方案 > 到达内部列表的结尾/开始时颤动嵌套列表滚动父级

问题描述

我正在 Flutter 中实现一个嵌套列表,当父列表到达末尾/开始内部列表时需要开始滚动父列表。我尝试了几种方法,没有一种运气。这是我尝试的最后一种方法。

这适用于从上到下,但是当我从下到上滚动时,它不会(父子滚动不平滑)。从下到上滚动时可能需要一些逻辑改进。

由于我是 Dart 的新手,任何人都可以帮我完成这项工作吗?

import 'dart:async';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(title: 'Flutter Demo', home: MyListView());
 }
}

class MyListView extends StatelessWidget {
  ScrollController _mainScrollController = ScrollController();
  double listHeight = 370;
  @override
  Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    title: const Text('AppBar'),
  ),
  body: Container(
    height: MediaQuery.of(context).size.height,
    child: ListView(
        controller: _mainScrollController,
        children: <Widget>[

          Container(height: listHeight,child: RapportList(parentScrollController: _mainScrollController)),
          OtherElement(text: "Other element 1 which will be scrolled",),
          OtherElement(text: "Other element 2 which will be scrolled",),
          OtherElement(text: "Other element 3 which will be scrolled",),
          OtherElement(text: "Other element 4 which will be scrolled",),
          OtherElement(text: "Other element 5 which will be scrolled",),
          Container(height: listHeight,child: RapportList(parentScrollController: _mainScrollController)),
           OtherElement(text: "Other element 4 which will be scrolled",),
          OtherElement(text: "Other element 5 which will be scrolled",),
          Container(height: listHeight,child: RapportList(parentScrollController: _mainScrollController)),


        ],
    ),
  ),
);
   }
  }

 class RapportList extends StatefulWidget {
    final ScrollController parentScrollController;
   RapportList({@required this.parentScrollController});
   @override
   _RapportListState createState() => _RapportListState();
     }

class _RapportListState extends State<RapportList> {
   ScrollPhysics physics = ScrollPhysics();
   // NeverScrollableScrollPhysics()
    ScrollController _listViewScrollController;


  void listViewScrollListener(){
     print("smth");
      if(_listViewScrollController.offset >= _listViewScrollController.position.maxScrollExtent &&
    !_listViewScrollController.position.outOfRange){
  if(widget.parentScrollController.offset==0){
    widget.parentScrollController.animateTo(50,duration: Duration(milliseconds: 200),curve: Curves.linear);
  }
  setState((){
    physics = NeverScrollableScrollPhysics();
  });
  print("bottom");
    }
   }

  void mainScrollListener(){
       if(widget.parentScrollController.offset <= widget.parentScrollController.position.minScrollExtent &&
    !widget.parentScrollController.position.outOfRange){
  setState((){
    if(physics is NeverScrollableScrollPhysics){
      physics = ScrollPhysics();
_listViewScrollController.animateTo(_listViewScrollController.position.maxScrollExtent-50,duration: Duration(milliseconds: 200),curve: Curves.linear);
    }
  });
  print("top");
   }
 }

 @override
 void setState(fn) {
   super.setState(fn);
 }
  @override
  void initState() {
    _listViewScrollController = ScrollController();
   _listViewScrollController.addListener(listViewScrollListener);

    // TODO: implement initState
    super.initState();
   }
   @override
   Widget build(BuildContext context) {

     widget.parentScrollController.addListener(mainScrollListener);
     return ListView.builder(
       controller: _listViewScrollController,
      physics: physics,
      shrinkWrap: true,
      itemCount: 50,
      itemBuilder: (context, index) {
        return ListTile(
         title: GestureDetector(
           child: Row(
             children: <Widget>[
               Container(child: Text("text $index")),
          ],
        ),
      ),
    );
  },
   );
  }
  }


 class OtherElement extends StatelessWidget {
  final String text;
  OtherElement({this.text});
   @override
    Widget build(BuildContext context) {
   return Container(
     height: 100,
     child: Center(child: Padding(
      padding: const EdgeInsets.symmetric(horizontal:40.0),
       child: Text(this.text,style:TextStyle(fontSize: 30)),
     )),
   );
   }
   }

这个想法完全来自这里:Flutter listview at the end of its content scrolls screen

标签: flutterlistviewflutter-layoutnestedscrollviewsinglechildscrollview

解决方案


推荐阅读