簡體   English   中英

Flutter listview 在其內容滾動屏幕的末尾

[英]Flutter listview at the end of its content scrolls screen

我想知道是否可以在SingleChildScrollView中有一個具有固定高度的垂直ListView並且當垂直ListView中沒有更多內容時,滾動將應用於整個屏幕( SingleChildScrollView

像這樣的東西:

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

我正在使用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)),
      )),
    );
  }
}

github 要點

演示 gif:

在此處輸入圖像描述

我想您可以嘗試使用Nested ScrollView Widget

此小部件使您能夠完成所需的工作。

我認為您更新的代碼有錯誤。 因為如果你在 SingleChildScrollView 中有一個 Scrollable ListView,你就不能滾動它。 讓它成為你必須將它添加到你的listView:

            physics: const NeverScrollableScrollPhysics(),

現在它應該可以工作了。 在大多數情況下,您也可以嘗試添加列而不是列表視圖。

更新@man of Knowledge 的代碼,

(ListView 中的 ListView)

飛鏢 2.15.1

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(_mainScrollController)),
            OtherElement(
              "Other element 1 which will be scrolled",
            ),
            OtherElement(
              "Other element 2 which will be scrolled",
            ),
            OtherElement(
              "Other element 3 which will be scrolled",
            ),
            OtherElement(
              "Other element 4 which will be scrolled",
            ),
            OtherElement(
              "Other element 5 which will be scrolled",
            ),
          ],
        ),
      ),
    );
  }
}

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

class _RapportListState extends State<RapportList> {
  late ScrollController _listViewScrollController = ScrollController()
    ..addListener(listViewScrollListener);
  ScrollPhysics _physics = ScrollPhysics();
  // NeverScrollableScrollPhysics()

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM