Ребенок ListView в родительском элементе ListView

Каков предпочтительный способ создания вложенного ListView, или, другими словами, виджета ListView, который может быть включен в прокручиваемый родитель?

Представьте себе страницу "Отчеты", где раздел является подробным списком.

Ответ 1

Если вы хотите, чтобы внутренний ListView можно было прокручивать независимо от основного представления прокрутки, вам следует использовать NestedScrollView. В противном случае используйте CustomScrollView.

Вот некоторый код, иллюстрирующий подход NestedScrollView.

video

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            new SliverAppBar(
              pinned: true,
              title: new Text('Flutter Demo'),
            ),
          ];
        },
        body: new Column(
          children: <Widget>[
            new FlutterLogo(size: 100.0, colors: Colors.purple),
            new Container(
              height: 300.0,
              child: new ListView.builder(
                itemCount: 60,
                itemBuilder: (BuildContext context, int index) {
                  return new Text('Item $index');
                },
              ),
            ),
            new FlutterLogo(size: 100.0, colors: Colors.orange),
          ],
        ),
      ),
    );
  }
}

Ответ 2

Для дочернего ListView используйте этот параметр:

shrinkWrap: true,
physics: ClampingScrollPhysics(),

Ответ 3

Снимок экрана:

enter image description here


Код:

var _container = Container(
  height: 200,
  color: Colors.blue,
  margin: EdgeInsets.symmetric(vertical: 10),
);

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text("ListView")),
    body: Padding(
      padding: const EdgeInsets.all(40.0),
      child: ListView( // parent ListView
        children: <Widget>[
          _container,
          _container,
          Container(
            height: 200, // give it a fixed height constraint
            color: Colors.teal,
            // child ListView
            child: ListView.builder(itemBuilder: (_, i) => ListTile(title: Text("Item ${i}"))),
          ),
          _container,
          _container,
          _container,
        ],
      ),
    ),
  );
}