【问题标题】:Flutter listview at the end of its content scrolls screenFlutter listview 在其内容滚动屏幕的末尾
【发布时间】:2021-02-06 12:45:04
【问题描述】:

我想知道是否有可能在SingleChildScrollView 中有一个具有固定高度的垂直ListView,并且当垂直ListView 中没有更多内容时,滚动将应用于整个屏幕(@987654324 @)

类似这样的:

SingleChildScrollView(
      child: Column(
          children: [
            // some widgets ....
            
            Container(
              constraints: BoxConstraints(maxHeight: 200),
              child: ListView.builder(
                // other settings
                scrollDirection: Axis.vertical,
              ),
            )
          ]
      )
  )

【问题讨论】:

    标签: flutter listview singlechildscrollview


    【解决方案1】:

    我使用的是 SingleChildScrollView 的 Listview,但它是一样的:

    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",),
                ],
            ),
          ),
        );
      }
    }
    
    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)),
          )),
        );
      }
    }
    

    githubgist.

    演示 gif:

    【讨论】:

    • 很好的例子。它适用于从上到下的滚动,您能否说明从下到上滚动需要做什么(我的意思是从上到下和从下到上)?仅供参考,我是新手,无法继续保持这种行为。如果我能在这方面得到帮助,那就太好了。
    【解决方案2】:

    我想你可以尝试使用Nested ScrollView Widget

    此小部件可让您完成所需的工作。

    【讨论】:

      【解决方案3】:

      我认为您更新的代码有错误。因为如果你在 SingleChildScrollView 中有一个 Scrollable ListView,你就不能滚动它。让它成为你必须将它添加到你的 listView:

                  physics: const NeverScrollableScrollPhysics(),
      

      现在它应该可以工作了。在大多数情况下,您也可以尝试添加列而不是列表视图。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-19
        • 1970-01-01
        • 2022-01-10
        • 2017-11-17
        • 1970-01-01
        • 1970-01-01
        • 2021-02-19
        相关资源
        最近更新 更多