[英]Flutter ExpansionPanelList inside a modalBottomSheet doesn't update state
[英]Flutter Item ExpansionPanelList doesn't change state
我正在尝试从 API 检索数据,这很好用。
之后,我想在 ExpansionPanelList 中显示我的数据,该列表由一种方法构建:
class _CartaPageState extends State<CartaPage> {
@override
Widget build(BuildContext context) {
// Nos suscribimos al provider
final productoService = Provider.of<ProductoService>(context);
final List<Producto> productos = productoService.productos;
_productosItems = productosToItem(productos);
return Scaffold(
body: Container(
height: double.infinity,
width: double.infinity,
child: ListView(
children: [
ExpansionPanelList(
animationDuration: Duration(milliseconds: 300),
expansionCallback: (int index, bool isExpanded) {
setState(() {
_productosItems[index].isExpanded = !isExpanded;
//productosItems[index].isExpanded = !productosItems[index].isExpanded;
});
},
//children: productosToItem(productoService.entrantes).map<ExpansionPanel>((Item item) {
children: _productosItems.map<ExpansionPanel>((Item item) {
return ExpansionPanel(
headerBuilder: (context, isExpanded) {
return ListTile(
title: Text(item.headerValue),
);
},
................
数据显示完美,但状态在我的 ItemModel 上没有刷新,我认为问题是因为每次触摸面板列表时小部件都会重绘,从 API 检索(再次)数据并且永远不会改变状态。
我该如何解决?
先感谢您
编辑: CartaPage 被包装:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ProductoService()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: CartaPage()
),
);
}
}
编辑2:
我同意我正在失去状态,这是将Product转换为Item的方法:
List<Item> productosToItem(List<Producto> productos) {
return List.generate(productos.length, (index) {
return Item(
headerValue: productos[index].tipo,
expandedValue: productos[index].nombre,
);
});
}
ExpansionPanel
是否将其isExpanded
设置为item.isExpanded
?
您可以从productosToItem()
生成的任何内容中获得isExpanded
状态。
当您调用setState
时,您将一个新构建setState
队列,它将再次调用productosToItem()
。 在不知道该方法的作用的情况下,我无能为力。
我建议您查看productosToItem
以及为什么它没有将isExpanded
设置为正确的值。
如果_productosItems[index].isExpanded
不是一个二传手,我想你正在失去状态。
编辑 1:
您可以创建一个内部状态列表来保持扩展状态:
class Item {
Item({
this.expandedValue,
this.headerValue,
this.producto,
this.isExpanded = false,
});
String expandedValue;
String headerValue;
Producto producto; // <------------- ADDED
bool isExpanded;
}
class _CartaPageState extends State<CartaPage> {
Map<Producto, bool> expanded = {}; // <------------- ADDED
@override
Widget build(BuildContext context) {
// Nos suscribimos al provider
final productoService = Provider.of<ProductoService>(context);
final List<Producto> productos = productoService.productos;
// NOTE: ----------- converted to a local variable
final _productosItems = productosToItem(productos);
return Scaffold(
body: Container(
height: double.infinity,
width: double.infinity,
child: ListView(
children: [
ExpansionPanelList(
key: ValueKey(productos.length), // <------------- ADDED
animationDuration: Duration(milliseconds: 300),
expansionCallback: (int index, bool isExpanded) {
// NOTE: ----------- updated
final producto = productos[index];
setState(() {
expanded[producto] = !isExpanded;
});
},
children: _productosItems.map<ExpansionPanel>((Item item) {
return ExpansionPanel(
isExpanded: expanded[item.producto], // <------------- ADDED
canTapOnHeader: true,
headerBuilder: (context, isExpanded) {
return ListTile(
title: Text(item.headerValue),
);
},
body: ListTile(
title: Text(item.expandedValue),
),
);
}).toList(),
),
],
),
),
);
}
List<Item> productosToItem(List<Producto> productos) {
// keep a list of previous map
final toRemove = Map<Producto, bool>.from(expanded);
final items = List.generate(productos.length, (index) {
final producto = productos[index];
// set initial expanded state
expanded.putIfAbsent(producto, () => false);
// the item will be retained
toRemove.remove(producto);
return Item(
headerValue: producto.tipo,
expandedValue: producto.nombre,
producto: producto,
isExpanded: expanded[producto],
);
});
if (toRemove.isNotEmpty) {
// cleanup unused items
expanded.removeWhere((key, _) => toRemove.containsKey(key));
}
return items;
}
}
key: ValueKey(productos.length),
是必需的,因为ExpansionPanelList
对神奇地出现或消失的项目表现key: ValueKey(productos.length),
奇怪。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.