在使用具有狀態項的串列視圖時,我遇到了非常棘手的問題。我也在這里解釋一個例子。
這個例子是關于購物車螢屏的,每個購物車專案都有一個按鈕來洗掉購物車專案。
問題是-我有一個Listview.builder(),并且在它的itemBuilder 中-每個專案都是另一個Stateful Widget,我將一個函式引數傳遞給該小部件,并且該小部件有一個IconButton并按下我正在呼叫該引數功能。在該函式中,我正在從串列中洗掉該專案。該專案已從串列中成功洗掉,但不知何故狀態未洗掉。
我的代碼在下面
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> list = [
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5",
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("My Cart"),
),
body: ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return CartComponent(
value: list[index],
onDelete: () {
setState(() {
list.removeAt(index);
});
},
);
},
),
);
}
}
class CartComponent extends StatefulWidget {
final String value;
final Function onDelete;
const CartComponent({Key? key, required this.value, required this.onDelete})
: super(key: key);
@override
State<CartComponent> createState() => _CartComponentState();
}
class _CartComponentState extends State<CartComponent> {
String? name;
@override
void initState() {
super.initState();
name = widget.value;
}
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(10),
child: SizedBox(
height: 80,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Text(
"$name",
style: const TextStyle(fontSize: 16),
),
),
IconButton(
onPressed: () {
widget.onDelete();
},
icon: const Icon(Icons.clear),
),
],
),
),
);
}
}
該專案已成功從串列中洗掉,并且串列長度也在減少,但從視圖方面來看,串列的最后一個元素正在被洗掉(但實際上從List中,最后一個專案沒有被洗掉)
uj5u.com熱心網友回復:
試試這個,在你的 CartComponent 中添加這個:
final Function(String) onDelete;
并按下按鈕:
onPressed: () {
widget.onDelete(widget.value);
},
并在 ListView 構建器中執行此操作:
ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return CartComponent(
key: UniqueKey(), // the very important part
value: list[index],
onDelete: (value) {
setState(() {
list.remove(value);
});
},
);
},
)
uj5u.com熱心網友回復:
您可以直接widget.value
在文本上使用Text(widget.value,
這將起作用。
您可以更改洗掉功能,例如
或者
final Function(String value) onDelete;
并傳值widget.onDelete(name!);
現在在 itemBuilder
return CartComponent(
key: ValueKey("item ${list[index]}"),
value: list[index],
onDelete: (v) {
list.remove(v);
print(v);
setState(() {});
},
);
},
目前,
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> list = [
"Item 1",
"Item 1",
"Item 2",
"Item 3",
"Item 3",
"Item 4",
"Item 5",
"Item 5",
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return CartComponent(
key: ValueKey("item ${list[index]}"),
value: list[index],
onDelete: () {
list.removeAt(index);
setState(() {});
},
);
},
),
);
}
}
class CartComponent extends StatefulWidget {
final String value;
final Function onDelete;
const CartComponent({
Key? key,
required this.value,
required this.onDelete,
}) : super(key: key);
@override
State<CartComponent> createState() => _CartComponentState();
}
class _CartComponentState extends State<CartComponent> {
String? value;
@override
void initState() {
super.initState();
value = widget.value;
}
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(10),
child: SizedBox(
height: 80,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Text(
value!,
style: const TextStyle(fontSize: 16),
),
),
IconButton(
onPressed: () => widget.onDelete(),
icon: const Icon(Icons.clear),
),
],
),
),
);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/506381.html