dart - 在 Flutter 中以编程方式展开 ExpansionTile
问题描述
我只是想ExpansionTile
在 Flutter 中使用,从我修改为这样的示例:
我想隐藏箭头并Switch
用来展开图块,可以吗?还是我需要以编程方式呈现子项的自定义小部件?基本上,我只需要显示/隐藏孩子
这是我的代码:
import 'package:flutter/material.dart';
void main() {
runApp(ExpansionTileSample());
}
class ExpansionTileSample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('ExpansionTile'),
),
body: 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 {
Entry(this.title,[this.question='',this.children = const <Entry>[]]);
final String title;
final String question;
final List<Entry> children;
}
// The entire multilevel list displayed by this app.
final List<Entry> data = <Entry>[
Entry(
'Chapter A',
'',
<Entry>[
Entry(
'Section A0',
'',
<Entry>[
Entry('Item A0.1'),
Entry('Item A0.2'),
Entry('Item A0.3'),
],
),
Entry('Section A1','text'),
Entry('Section A2'),
],
),
Entry(
'Chapter B',
'',
<Entry>[
Entry('Section B0'),
Entry('Section B1'),
],
),
Entry(
'Chapter C',
'',
<Entry>[
Entry('Section C0'),
Entry('Section C1')
],
),
];
// Displays one Entry. If the entry has children then it's displayed
// with an ExpansionTile.
class EntryItem extends StatelessWidget {
const EntryItem(this.entry);
final Entry entry;
Widget _buildTiles(Entry root) {
if (root.children.isEmpty) return Container(
child:Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 32.0,
),
child:Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:[
Text(root.title),
Divider(height: 10.0,),
root.question=='text'?Container(
width: 100.0,
child:TextField(
decoration: const InputDecoration(helperText: "question")
),
):Divider()
]
)
)
);
return ExpansionTile(
//key: PageStorageKey<Entry>(root),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:[
Text(root.title),
Switch(
value:false,
onChanged: (_){},
)
]
),
children: root.children.map(_buildTiles).toList(),
);
}
@override
Widget build(BuildContext context) {
return _buildTiles(entry);
}
}
解决方案
@diegoveloper 的回答几乎没问题,一个未涵盖的小问题是:它不会将点击Switch
进一步传播到ExpansionTile
,所以如果您点击外部开关,它会扩大,而点击Switch
什么也不做。用 包裹它IgnorePointer
,并在展开事件时设置 switch 的值。这有点倒退的逻辑,但效果很好。
...
return ExpansionTile(
onExpansionChanged: _onExpansionChanged,
// IgnorePointeer propogates touch down to tile
trailing: IgnorePointer(
child: Switch(
value: isExpanded,
onChanged: (_) {},
),
),
title: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(root.title),
]),
children: root.children.map((entry) => EntryItem(entry)).toList(),
);
...
推荐阅读
- javascript - 如何知道数组是单维还是多维?
- javascript - MetaMask Web3 对象不支持没有回调参数的同步方法,例如 eth_sendTransaction
- php - PHP,如何计算日期范围以获取值
- python - python try/except 在循环中
- ios - 我试图快速创建一个本地数据库,它将数据传递给视图控制器中的元素
- javascript - Google 表格中的倒数计时器
- python - 将来自不同 hdf5 数据集的 numpy 数组组装到一个文件中
- ios - Hls 流 url 不会在 AVPlayer 中播放
- swagger - 使用带有 grails 4 的 Micronaut OpenAPI/Swagger 生成器
- omnet++ - 如何在静脉模拟中使用inet模块