一个领域的初学者,我有这段代码可以工作,但是在单击的情况下出现错误 当我单击任何卡片时,所有卡片也会打开。我想打开一张我只需点击的卡片
import 'dart:io';
import 'package:english_club/data/im.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class Novals extends StatefulWidget {
@override
_NovalsState createState()
{
return _NovalsState();
}
}
class _NovalsState extends State<Novals> {
bool _expanded = false;
var _test = "Full Screen";
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: ListView.builder(
itemCount: storys.length,
itemBuilder: (context, index){
return SingleChildScrollView(
child: Column(
children: [
Center(
child: Container(
margin: EdgeInsets.all(10),
color: Colors.green,
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 2000),
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return ListTile(
title: Text(storys[index]["name"], style: TextStyle(color: Colors.black),),
);
},
body:ListTile(
title: Text(storys[index]["lines"],style: TextStyle(color: Colors.black)),
),
isExpanded: _expanded,
canTapOnHeader: true,
),
],
dividerColor: Colors.grey,
expansionCallback: (panelIndex, isExpanded) {
_expanded = !_expanded;
setState(() {
});
},
),
),
),
]
),
);
}
),
);
}
}
我试图解决这个问题,但我无法让代码显示故事的名称,当用户点击它时,整个故事就会出现
首先,您应该删除
SingleChildScrollView
作为 ListView
子项。 ListView.builder
足以为您的 Scaffold
提供滚动功能。
对于主要问题,您应该将每个项目拆分为具有自己的
Widget
状态的单独 _expanded
。这将使您的 UI 更快,小部件将单独展开,并且整个屏幕无需在每个项目 setState()
后重新加载。
示例代码:
class Novals extends StatefulWidget {
@override
_NovalsState createState()
{
return _NovalsState();
}
}
class _NovalsState extends State<Novals> {
var _test = "Full Screen";
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: ListView.builder(
itemCount: storys.length,
itemBuilder: (context, index){
return StoryWidget(story: storys[index]);
}
),
);
}
}
class StoryWidget extends StatefulWidget {
final Map<String, dynamic> story;
const StoryWidget({Key? key, required this.story}) : super(key: key);
@override
_StoryWidgetState createState() => _StoryWidgetState();
}
class _StoryWidgetState extends State<StoryWidget> {
bool _expanded = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
Center(
child: Container(
margin: EdgeInsets.all(10),
color: Colors.green,
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 2000),
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return ListTile(
title: Text(widget.story["name"], style: TextStyle(color: Colors.black),),
);
},
body:ListTile(
title: Text(widget.story["lines"],style: TextStyle(color: Colors.black)),
),
isExpanded: _expanded,
canTapOnHeader: true,
),
],
dividerColor: Colors.grey,
expansionCallback: (panelIndex, isExpanded) {
_expanded = !_expanded;
setState(() {});
},
),
),
),
]
);
}
}
P/s:最好使用
story
将您的 jsonDecode()
放入模型类中,而不是直接使用 Map
。从长远来看,它将帮助您避免错误并更好地进行维护
问题是您对
_expanded
中的项目使用相同的 ListView
变量。
class _NovalsState extends State<Novals> {
bool _expanded = false;
...
@override
Widget build(BuildContext context) {
...
}
}
因此,当您在
itemBuilder
中调用 ListView
时,它会对每个项目使用相同的 _expanded
值。
解决方案:
将
_expanded
变量从 State
移动到 itemBuilder
函数体内。
class _NovalsState extends State<Novals> {
var _test = "Full Screen";
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: ListView.builder(
itemCount: storys.length,
itemBuilder: (context, index) {
bool _expanded = false;
return SingleChildScrollView(
child: Column(children: [
Center(
child: Container(
margin: EdgeInsets.all(10),
color: Colors.green,
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 2000),
children: [
ExpansionPanel(
headerBuilder: (context, isExpanded) {
return ListTile(
title: Text(
storys[index]["name"],
style: TextStyle(color: Colors.black),
),
);
},
body: ListTile(
title: Text(storys[index]["lines"],
style: TextStyle(color: Colors.black)),
),
isExpanded: _expanded,
canTapOnHeader: true,
),
],
dividerColor: Colors.grey,
expansionCallback: (panelIndex, isExpanded) {
_expanded = !_expanded;
setState(() {});
},
),
),
),
]),
);
}),
);
}
}
查看 Dart 的词法范围
我在 ExpansionPanelList 中显示评论列表。列表中的每个注释都映射为扩展面板的注释类型。扩展面板使用 isExpanded 值来确定它是折叠还是展开。 ExpansionPanelList 回调扩展回调是在折叠或展开事件切换值时调用的。
class Comment {
final String title;
final String body;
bool isExpanded = false;
Comment(this.title, this.body);
}
ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
_commentsList[index].isExpanded = !isExpanded;
});
},
children: _commentsList
.map<ExpansionPanel>((Comment comment) {
return ExpansionPanel(
headerBuilder:
(BuildContext context, bool isExpanded) {
return const ListTile(title: Text("Comments"));
},
body: Column(
children: [
Text(comment.body),
],
),
isExpanded: comment.isExpanded,
);
}).toList(),
)