flutter - 当我从列表中删除项目并执行 setState((){}) 时,颜色状态正在发生变化
问题描述
我在颤动中为 ListTile 前导属性分配随机颜色,但是当我使用 setState 删除一个项目时,所有列表项的颜色都在变化,我尝试使用 ObjectKey() ,我想保持颜色状态不变
ListTile(
key: ObjectKey(expense),
onTap: () {
setState(() {
_allExpenses.remove(expense);
});
},
leading: CircleAvatar(
radius: 20,
backgroundColor: Color(Random().nextInt(0xffffffff)),
child: FindIcon(expense.type),
),
title: Text("Test"),
)
我正在使用提供者和 notifyListeners(); 这使得在每个项目删除时重建 UI
解决方案
在您的情况下,setState
每次都会重建。如果要使用s,则必须创建key
一个新的包装器。ListTile
但是,还有另一种选择。在 中initState
,可以创建随机颜色列表:
class MyList extends StatefulWidget {
const MyList({ Key key }) : super(key: key);
@override
_MyListState createState() => _MyListState();
}
class _MyListState extends State<MyList> {
final List<int> _allExpenses = [2, 4, 5, 6, 9, 10, 22];
List<Color> _colors;
@override
void initState(){
super.initState();
_colors = [
for(final _ in _allExpenses)
Color(Random().nextInt(0xffffffff)),
];
}
void removeOne(int index){
setState(() {
_allExpenses.removeAt(index);
_colors.removeAt(index);
});
}
@override
Widget build(BuildContext context) {
return ListView(
children: [
for(int i = 0; i < _allExpenses.length; i++)
ListTile(
//key: ObjectKey(expense),
onTap: () => removeOne(i),
leading: CircleAvatar(
radius: 20,
backgroundColor: _colors[i],
child: Icon(Icons.account_circle),
),
title: Text("Test ${_allExpenses[i]}"),
),
]
);
}
}
这是一个很好的选择,因为您可以控制这些随机颜色所需的内存。该逻辑可以通过在s中使用扩展至ChangeNotifier
s :notifyListeners()
addListener()
initState
@override initState(){
...
myChangeNotifierList.addListener(() => setState((){}));
}
还有另一种选择,您可以委托处理随机颜色并保持每个列表图块的状态。
class MyListWithKeys extends StatefulWidget {
const MyListWithKeys({ Key key }): super(key: key);
@override
_MyListWithKeysState createState() => _MyListWithKeysState();
}
class _MyListWithKeysState extends State<MyListWithKeys> {
final List<int> _allExpenses = [2, 4, 5, 6, 9, 10, 22];
void removeOne(int expense){
setState(() {
_allExpenses.remove(expense);
});
}
@override
Widget build(BuildContext context) {
return ListView(
children: [
for(final expense in _allExpenses)
MyTile(
key: ObjectKey(expense),
expense: expense,
onTap: () => removeOne(expense),
),
]
);
}
}
class MyTile extends StatefulWidget {
const MyTile({
Key key,
@required this.expense,
@required this.onTap,
}) : assert(expense != null),
assert(onTap != null),
super(key: key);
final int expense;
final VoidCallback onTap;
@override
_MyTileState createState() => _MyTileState();
}
class _MyTileState extends State<MyTile> {
Color _color;
@override
void initState() {
super.initState();
_color = Color(Random().nextInt(0xffffffff));
}
@override
Widget build(BuildContext context) {
return ListTile(
onTap: widget.onTap,
leading: CircleAvatar(
radius: 20,
backgroundColor: _color,
child: Icon(Icons.account_circle),
),
title: Text('Test ${widget.expense}'),
);
}
}
推荐阅读
- python - 从字符串复制子字符串并打印子字符串的长度
- sql - 如何修复“使用 SQL 中的条件选择行”
- facebook-pixel - facebook 像素事件“ViewContent”必须有参数 content_type 和 content_ids?
- angular - rxjs-websockets - 如何封装为 Angular 6/7 服务
- javascript - Selenium Webdriver 不执行 JavaScript
- javascript - 如何在页面加载后显示跨度标签
- rabbitmq - RabbitMQ StompJs 只收到一条消息
- c++ - 将 std::filesystem 添加到 CMake 项目时出现问题
- java - 如何在 selenium Web 驱动程序中的剩余元素上提取或选择特定日期和时间
- php - 致命错误:未捕获的错误:在类中找不到类“htmlMimeMail”未找到错误