Flutter 带有ListView.builder的Flatter ExpansionFile存在奇怪的垂直滚动问题

Flutter 带有ListView.builder的Flatter ExpansionFile存在奇怪的垂直滚动问题,flutter,listview,scroll,Flutter,Listview,Scroll,下面我举了一个我的问题的例子。当使用ListView.builder()使用ExpansionFile()惰性地构建列表中的项目时,我有一种奇怪的行为,即无法通过从打开的扩展磁贴中抓取项目来滚动整个列表。如果我在列表顶层的一个基本项上获取整个列表,那么我仍然可以滚动整个列表 我编写了一个演示应用程序来展示这一点 如果将bool标志swapFailureTrigger设置为true,则不会对打开的扩展磁贴内容使用ListView.builder(),而是将其全部放在内存中。然后,无论您在哪里抓取列

下面我举了一个我的问题的例子。当使用ListView.builder()使用ExpansionFile()惰性地构建列表中的项目时,我有一种奇怪的行为,即无法通过从打开的扩展磁贴中抓取项目来滚动整个列表。如果我在列表顶层的一个基本项上获取整个列表,那么我仍然可以滚动整个列表

我编写了一个演示应用程序来展示这一点

如果将bool标志swapFailureTrigger设置为true,则不会对打开的扩展磁贴内容使用ListView.builder(),而是将其全部放在内存中。然后,无论您在哪里抓取列表,都可以顺利地垂直滚动

如果将bool标志swapFailureTrigger设置为false,则它将使用ListView.builder(),您可以通过打开扩展磁贴并通过抓取扩展列表中的项目尝试垂直滚动来体验失败

我不确定这是否与我使用的钥匙有关

import 'package:flutter/material.dart';

// If TRUE, scrolling works well when grabbing an open expansion tile list
// If FALSE, scrolling only works if you grab a parent list OUTSIDE the items of the open expansion tile
bool swapFailureTrigger = false;

class EntryItem extends StatelessWidget {
  const EntryItem(this.entry);

  final Entry entry;

  Widget _buildTiles(Entry root) {
    if (root.children.isEmpty) return ListTile(title: Text(root.title));
    var kids = root.children.map((child) => _buildTiles(child)).toList();

    return ExpansionTile(
      key: PageStorageKey<Entry>(root),
      title: Text(root.title),

      // <<---------- PROBLEM IS HERE if you test with the ListView.builder() version ---------->>
      children: swapFailureTrigger ?
      root.children.map(_buildTiles).toList():
      <Widget>[
        ListView.builder(
          key: PageStorageKey<Entry>(root),
          itemCount: kids.length,
          itemBuilder: (context, index) {
            return kids[index];
          },
          shrinkWrap: true,
        )
      ],
      //  <<--------------------------------------------------------------------------------->>


    );
  }

  @override
  Widget build(BuildContext context) {
    return _buildTiles(entry);
  }
}

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Expansion Issue'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ExpansionTileExample(),
    );
  }
}

class ExpansionTileExample extends StatelessWidget {
  const ExpansionTileExample({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (BuildContext context, int index) => EntryItem(data[index]),
      itemCount: data.length,
    );
  }
}

// One entry in the multilevel list displayed by this app.
class Entry {
  const Entry(this.title, [this.children = const <Entry>[]]);
  final String title;
  final List<Entry> children;
}

// Data to display.
const List<Entry> data = <Entry>[
  Entry(
    'Chapter A',
    <Entry>[
      Entry(
        'Section A0',
        <Entry>[
          Entry('Item A0.1'),
          Entry('Item A0.2'),
        ],
      ),
      Entry('Section A1'),
      Entry('Section A2'),
      Entry('Section A3'),
      Entry('Section A4'),
      Entry('Section A5'),
      Entry('Section A6'),
      Entry('Section A7'),
      Entry('Section A8'),
      Entry('Section A9'),
      Entry('Section A10'),
      Entry('Section A11'),
      Entry('Section A12'),
      Entry('Section A13'),
      Entry('Section A14'),
      Entry('Section A15'),
      Entry('Section A16'),
      Entry('Section A17'),
      Entry('Section A18'),
      Entry('Section A19'),
    ],
  ),
  Entry(
    'Chapter B',
    <Entry>[
      Entry('Section B1'),
      Entry('Section B2'),
      Entry('Section B3'),
      Entry('Section B4'),
      Entry('Section B5'),
      Entry('Section B6'),
      Entry('Section B7'),
      Entry('Section B8'),
      Entry('Section B9'),
      Entry('Section B10'),
      Entry('Section B11'),
      Entry('Section B12'),
      Entry('Section B13'),
      Entry('Section B14'),
      Entry('Section B15'),
      Entry('Section B16'),
      Entry('Section B17'),
      Entry('Section B18'),
      Entry('Section B19'),
    ],
  ),
  Entry(
    'Chapter C',
    <Entry>[
      Entry('Section C1'),
      Entry('Section C2'),
      Entry('Section C3'),
      Entry('Section C4'),
      Entry('Section C5'),
      Entry('Section C6'),
      Entry('Section C7'),
      Entry('Section C8'),
      Entry('Section C9'),
      Entry('Section C10'),
      Entry('Section C11'),
      Entry('Section C12'),
      Entry('Section C13'),
      Entry('Section C14'),
      Entry('Section C15'),
      Entry('Section C16'),
      Entry('Section C17'),
      Entry('Section C18'),
      Entry('Section C19'),
    ],
  ),
  Entry(
    'Chapter D',
    <Entry>[
      Entry('Section D1'),
      Entry('Section D2'),
      Entry('Section D3'),
      Entry('Section D4'),
      Entry('Section D5'),
      Entry('Section D6'),
      Entry('Section D7'),
      Entry('Section D8'),
      Entry('Section D9'),
      Entry('Section D10'),
      Entry('Section D11'),
      Entry('Section D12'),
      Entry('Section D13'),
      Entry('Section D14'),
      Entry('Section D15'),
      Entry('Section D16'),
      Entry('Section D17'),
      Entry('Section D18'),
      Entry('Section D19'),
    ],
  ),
  Entry(
    'Chapter E',
    <Entry>[
      Entry('Section E1'),
      Entry('Section E2'),
      Entry('Section E3'),
      Entry('Section E4'),
      Entry('Section E5'),
      Entry('Section E6'),
      Entry('Section E7'),
      Entry('Section E8'),
      Entry('Section E9'),
      Entry('Section E10'),
      Entry('Section E11'),
      Entry('Section E12'),
      Entry('Section E13'),
      Entry('Section E14'),
      Entry('Section E15'),
      Entry('Section E16'),
      Entry('Section E17'),
      Entry('Section E18'),
      Entry('Section E19'),
    ],
  ),
];
导入“包装:颤振/材料.省道”;
//如果为TRUE,则在抓取打开的扩展平铺列表时滚动效果良好
//如果为FALSE,则仅当您在打开的扩展磁贴的项目外部获取父列表时,滚动才有效
bool-swapFailureTrigger=false;
类EntryItem扩展了无状态小部件{
const EntryItem(此项);
最终入围;
Widget\u buildTiles(条目根){
if(root.children.isEmpty)返回ListTile(标题:Text(root.title));
var kids=root.children.map((child)=>\u buildTiles(child)).toList();
返回扩展文件(
密钥:PageStorageKey(根),
标题:文本(root.title),
// 
孩子们:swapFailureTrigger?
root.children.map(\u buildTiles.toList():
[
ListView.builder(
密钥:PageStorageKey(根),
itemCount:kids.length,
itemBuilder:(上下文,索引){
返回儿童[索引];
},
收缩膜:对,
)
],
//  
);
}
@凌驾
小部件构建(构建上下文){
返回(条目);;
}
}
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:我的主页(标题:“颤振扩展问题”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
int _计数器=0;
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:ExpansionTileExample(),
);
}
}
类ExpansionTileExample扩展了无状态小部件{
const ExpansionTileExample({Key}):super(Key:Key);
@凌驾
小部件构建(构建上下文){
返回ListView.builder(
itemBuilder:(BuildContext上下文,int-index)=>EntryItem(数据[index]),
itemCount:data.length,
);
}
}
//此应用程序显示的多级列表中的一个条目。
班级报名{
常量条目(this.title[this.children=const[]);
最后的字符串标题;
最后儿童名单;
}
//要显示的数据。
常量列表数据=[
入口(
“A章”,
[
入口(
“第A0节”,
[
条目(“第A0.1项”),
条目(“第A0.2项”),
],
),
条目(“第A1节”),
条目(“第A2节”),
条目(“第A3节”),
条目(“第A4节”),
条目(“第A5节”),
条目(“第A6节”),
条目(“第A7节”),
条目(“第A8节”),
条目(“第A9节”),
条目(“第A10节”),
条目(“第A11节”),
条目(“第A12节”),
条目(“第A13节”),
条目(“第A14节”),
条目(“第A15节”),
条目(“第A16节”),
条目(“第A17节”),
条目(“第A18节”),
条目(“第A19节”),
],
),
入口(
“B章”,
[
条目(“B1节”),
条目(“第B2节”),
条目(“B3节”),
条目(“B4节”),
条目(“第B5节”),
条目(“B6节”),
条目(“B7节”),
条目(“B8节”),
条目(“B9节”),
条目(“第B10节”),
条目(“第B11节”),
条目(“第B12节”),
条目(“第B13节”),
条目(“第B14节”),
条目(“第B15节”),
条目(“第B16节”),
条目(“第B17节”),
条目(“第B18节”),
条目(“第B19节”),
],
),
入口(
"C章",,
[
条目(“第C1节”),
条目(“第C2节”),
条目(“第C3节”),
条目(“第C4节”),
条目(“第C5节”),
条目(“第C6节”),
条目(“第C7节”),
条目(“第C8节”),
条目(“第C9节”),
条目(“第C10节”),
条目(“第C11节”),
条目(“第C12节”),
条目(“第C13节”),
条目(“第C14节”),
条目(“第C15节”),
条目(“第C16节”),
条目(“第C17节”),
条目(“第C18节”),
条目(“第C19节”),
],
),
入口(
"D章",,
[
条目(“第D1节”),
条目(“第D2节”),
条目(“第D3节”),
条目(“第D4节”),
条目(“第D5节”),
条目(“第D6节”),
条目(“第D7节”),
条目(“第D8节”),
条目(“第D9节”),
条目(“第D10节”),
条目(“第D11节”),
条目(“第D12节”),
条目(“第D13节”),
条目(“第D14节”),
条目(“第D15节”),
条目(“第D16节”),
条目(“第D17节”),
条目(“第D18节”),
条目(“第D19节”),
],
),
入口(
“E章”,
[
条目(“第E1节”),
条目(“E2节”),
条目(“第E3节”),
条目(“第E4节”),
条目(“第E5节”),
条目(“第E6节”),
条目(“第E7节”),
条目(‘第E8节’)
 physics: ClampingScrollPhysics(),