1

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

像这样的东西:

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

3 回答 3

2

我正在使用 Listview insted,SingleChildScrollView但它是相同的:

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:

在此处输入图像描述

于 2020-10-23T15:42:30.193 回答
0

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

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

于 2020-10-23T13:08:45.107 回答
0

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

            physics: const NeverScrollableScrollPhysics(),

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

于 2020-10-23T13:44:30.773 回答