我有以下问题,我想将常规列表视图添加到可扩展列表视图的扩展部分,我已尝试使用以下代码进行操作:
body: ListTile(
leading: Checkbox(
value: info.completed,
onChanged: (value) {
setState(() {
// Here you toggle the checked item state
infos.firstWhere((currentInfo) => info == currentInfo)
..completed = value;
});
}),
title: ListView.builder(
itemCount: info.expandedValueData.length ,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(info.expandedValueData[index].title,
style: TextStyle(
decoration: info.completed
? TextDecoration.lineThrough
: null))),
);
},),
subtitle: Text(
"Drücke auf den Mülleimer, um diesen Abschnitt bis zum Neustart der App zu löschen"),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
infos.removeWhere((currentInfo) => info == currentInfo);
});
},
)),
这样我就没有收到任何错误,但是如果我打开一个列表磁贴,它并没有描绘出我想要的数据,它只是空的,这里有一张图片:
有什么建议我做错了什么以及如何解决吗?
编辑:所以这或多或少是基本代码,我找到了部分问题的解决方案(第 62 行),您将看到是否测试了描述列表的代码,但无论如何,我获取渲染 Flex 溢出,并且可扩展部分中的每个文本图块旁边都没有放置可勾选框
这里是完整的代码(可能添加了我应该添加的更多数据)
import 'package:flutter/material.dart';
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: Scaffold(
body: ExpansionTile(
title: Text("Generelles Vorgehen"),
children: [ExpansionList()],
),
),
);
}
}
class ExpansionList extends StatefulWidget {
final Info info;
const ExpansionList({
Key key,
this.info,
}) : super(key: key);
@override
_ExpansionListState createState() => _ExpansionListState();
}
class _ExpansionListState extends State<ExpansionList> {
Widget _buildListPanel() {
return ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
infos[index].isExpanded = !isExpanded;
});
},
children: infos.map<ExpansionPanel>((Info info) {
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(info.headerValue),
);
},
body: ListTile(
leading: Checkbox(
value: info.completed,
onChanged: (value) {
setState(() {
// Here you toggle the checked item state
infos.firstWhere((currentInfo) => info == currentInfo)
..completed = value;
});
}),
title: SizedBox(
height: 200, //this was the solution I dont know why, but you have to specify a hight here, so that the content gets whon
child: ListView.builder(
itemCount: info.expandedValueData.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(info.expandedValueData[index].title,
style: TextStyle(
decoration: info.completed
? TextDecoration.lineThrough
: null))),
);
},
),
),
subtitle: Text(
"Drücke auf den Mülleimer, um diesen Abschnitt bis zum Neustart der App zu löschen"),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
infos.removeWhere((currentInfo) => info == currentInfo);
});
},
)),
isExpanded: info.isExpanded);
}).toList(),
);
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
child: _buildListPanel(),
),
);
}
}
class expandedValue{
final int id;
final String title;
const expandedValue({
this.id,
this.title,
});
}
class Info {
String headerValue;
bool isExpanded;
bool completed;
final List<expandedValue> expandedValueData;
Info(
{this.headerValue,
this.isExpanded = false,
this.completed = false,
this.expandedValueData});
}
List<Info> infos = [
Info(
headerValue: "Außenansicht",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "Roststellen"),
expandedValue(
id: 2,
title:
"Farbunterschiede im Lack, Unregelmäßigkeiten [Problemstellen übermalt]"),
expandedValue(
id: 3,
title: "kleine Kratzer [hinter Karosserie größere Folgeschäden?]"),
expandedValue(
id: 4, title: "Dichtungen an Scheiben & Türen [porös, rissig]"),
expandedValue(
id: 5,
title:
"Vorallem Windschutzscheibe auf Kratzer untersuchen [Gefahr größerer Rissbildung ]"),
expandedValue(
id: 6,
title:
"Lampen untersuchen, funktionsfähig? Innen beschlagene Scheinwerfer [Gefahr durch Wasserschaden]"),
expandedValue(id: 7, title: "Reifen [Risse o. abgefahrenes Profil?]"),
],
),
Info(
headerValue: "Innenraum",
expandedValueData: <expandedValue>[
expandedValue(
id: 1,
title: "klappern Türen oder deren Seitenverkleidung beim Schließen?"),
expandedValue(id: 2, title: "funktionierende Elektrik"),
expandedValue(id: 3, title: "Sitze"),
expandedValue(id: 4, title: "Rest"),
],
),
Info(
headerValue: "Motorraum",
expandedValueData: <expandedValue>[
expandedValue(
id: 1,
title:
"Motor schon vom Verkäufer warmgelaufen? [eventuell sollen Startprobleme vertuscht werden]"),
expandedValue(
id: 2,
title: "Batteriepole angerostet? [Gefahr vorzeitiger Entladung]"),
expandedValue(
id: 3, title: "Gibt es Öl oder Bremsflüssigkeitsspuren an:"),
expandedValue(
id: 4,
title:
"Sprudelt Kühlswasser bei laufendem Motor [eventuell Zylinderkopfdichtung defekt]"),
expandedValue(id: 5, title: "Ölstand prüfen"),
],
),
Info(
headerValue: "Unterboden",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "Roststellen?"),
expandedValue(
id: 2,
title:
"neuer Unterbodenschutz? [möglicher Versuch Problemstellen zu verdecken (z.B Schweißnähte etc.)]"),
expandedValue(
id: 3, title: "sitzt der Auspuff fest, arbeitet der Motor leise?"),
],
),
Info(
headerValue: "Dokumenten- & Zahlencheck",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "Reperaturenabrechnungen vorhanden?"),
expandedValue(
id: 2,
title:
"macht Laufleistung Sinn? Mögliche Lufleistungen im Bereich von über 150 000 km, wenn:"),
expandedValue(id: 3, title: "Zulassungsbescheinigung Teil 1&2 "),
expandedValue(id: 4, title: "Wartungen & Rechnungen"),
],
),
Info(
headerValue: "Probefahrt",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "vor der Fahrt:"),
expandedValue(id: 2, title: "bei der Fahrt"),
expandedValue(id: 3, title: "nach der Fahrt"),
],
),
Info(
headerValue: "Garantie, Gewehrleistung und Vertrag ",
expandedValueData: <expandedValue>[
expandedValue(
id: 1,
title:
"auf Rechmäßigkeit prüfen, wegen Haftungsgründen verweisen wir hier auf andere Seiten, wie die der Allianz oder Cosmosdirekt o. ä. "),
],
),
];
答案 0 :(得分:1)
要解决溢出问题,您可以将小部件包装在 SingleChildScrollView
中,只要您绘制的内容超过屏幕上的可用空间,您就应该使用它或 ListView 来滚动。
至于每个磁贴旁边的复选框,您在创建每个 ListView.builder
的 expandedValue
之前绘制复选框,因此它只为包含 listivew 的 listTile 创建一次,而不是为每个项目创建。在 listview.builder 中构造复选框可以解决这个问题。
我还在 expandedValue
类中添加了一个布尔属性,以便能够单独检查每个项目(IDK,如果这是您正在寻找的行为)。
import 'package:flutter/material.dart';
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',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: SingleChildScrollView(
child: ExpansionTile(
title: Text("Generelles Vorgehen"),
children: [ExpansionList()],
),
),
),
);
}
}
class ExpansionList extends StatefulWidget {
final Info info;
const ExpansionList({
Key key,
this.info,
}) : super(key: key);
@override
_ExpansionListState createState() => _ExpansionListState();
}
class _ExpansionListState extends State<ExpansionList> {
Widget _buildListPanel() {
return ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
infos[index].isExpanded = !isExpanded;
});
},
children: infos.map<ExpansionPanel>((Info info) {
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(info.headerValue),
);
},
body: ListTile(
title: SizedBox(
height: 200,
//this was the solution I dont know why, but you have to specify a hight here, so that the content gets whon
child: ListView.builder(
itemCount: info.expandedValueData.length,
itemBuilder: (context, index) {
var currentExpandedValue=info.expandedValueData[index];
return Card(
child: ListTile(
leading: Checkbox(
value: currentExpandedValue.newlyIsExpandedValue,
onChanged: (value) {
setState(() {
// Here you toggle the checked item state
currentExpandedValue.newlyIsExpandedValue=value;
});
}),
title: Text(info.expandedValueData[index].title,
style: TextStyle(decoration: currentExpandedValue.newlyIsExpandedValue ? TextDecoration.lineThrough : null)),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
info.expandedValueData.removeWhere((currentInfo) => currentExpandedValue == currentInfo);
});
},
),
),
);
},
),
),
subtitle: Text("Drücke auf den Mülleimer, um diesen Abschnitt bis zum Neustart der App zu löschen"),
),
isExpanded: info.isExpanded);
}).toList(),
);
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
child: _buildListPanel(),
),
);
}
}
class expandedValue {
final int id;
final String title;
bool newlyIsExpandedValue;
expandedValue( {
this.id,
this.title,
this.newlyIsExpandedValue=false,
});
}
class Info {
String headerValue;
bool isExpanded;
bool completed;
final List<expandedValue> expandedValueData;
Info({this.headerValue, this.isExpanded = false, this.completed = false, this.expandedValueData});
}
List<Info> infos = [
Info(
headerValue: "Außenansicht",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "Roststellen"),
expandedValue(id: 2, title: "Farbunterschiede im Lack, Unregelmäßigkeiten [Problemstellen übermalt]"),
expandedValue(id: 3, title: "kleine Kratzer [hinter Karosserie größere Folgeschäden?]"),
expandedValue(id: 4, title: "Dichtungen an Scheiben & Türen [porös, rissig]"),
expandedValue(id: 5, title: "Vorallem Windschutzscheibe auf Kratzer untersuchen [Gefahr größerer Rissbildung ]"),
expandedValue(
id: 6,
title: "Lampen untersuchen, funktionsfähig? Innen beschlagene Scheinwerfer [Gefahr durch Wasserschaden]"),
expandedValue(id: 7, title: "Reifen [Risse o. abgefahrenes Profil?]"),
],
),
Info(
headerValue: "Innenraum",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "klappern Türen oder deren Seitenverkleidung beim Schließen?"),
expandedValue(id: 2, title: "funktionierende Elektrik"),
expandedValue(id: 3, title: "Sitze"),
expandedValue(id: 4, title: "Rest"),
],
),
Info(
headerValue: "Motorraum",
expandedValueData: <expandedValue>[
expandedValue(
id: 1, title: "Motor schon vom Verkäufer warmgelaufen? [eventuell sollen Startprobleme vertuscht werden]"),
expandedValue(id: 2, title: "Batteriepole angerostet? [Gefahr vorzeitiger Entladung]"),
expandedValue(id: 3, title: "Gibt es Öl oder Bremsflüssigkeitsspuren an:"),
expandedValue(id: 4, title: "Sprudelt Kühlswasser bei laufendem Motor [eventuell Zylinderkopfdichtung defekt]"),
expandedValue(id: 5, title: "Ölstand prüfen"),
],
),
Info(
headerValue: "Unterboden",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "Roststellen?"),
expandedValue(
id: 2,
title: "neuer Unterbodenschutz? [möglicher Versuch Problemstellen zu verdecken (z.B Schweißnähte etc.)]"),
expandedValue(id: 3, title: "sitzt der Auspuff fest, arbeitet der Motor leise?"),
],
),
Info(
headerValue: "Dokumenten- & Zahlencheck",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "Reperaturenabrechnungen vorhanden?"),
expandedValue(
id: 2, title: "macht Laufleistung Sinn? Mögliche Lufleistungen im Bereich von über 150 000 km, wenn:"),
expandedValue(id: 3, title: "Zulassungsbescheinigung Teil 1&2 "),
expandedValue(id: 4, title: "Wartungen & Rechnungen"),
],
),
Info(
headerValue: "Probefahrt",
expandedValueData: <expandedValue>[
expandedValue(id: 1, title: "vor der Fahrt:"),
expandedValue(id: 2, title: "bei der Fahrt"),
expandedValue(id: 3, title: "nach der Fahrt"),
],
),
Info(
headerValue: "Garantie, Gewehrleistung und Vertrag ",
expandedValueData: <expandedValue>[
expandedValue(
id: 1,
title:
"auf Rechmäßigkeit prüfen, wegen Haftungsgründen verweisen wir hier auf andere Seiten, wie die der Allianz oder Cosmosdirekt o. ä. "),
],
),
];