ListView flutter 中如何管理不同小部件的状态?
Posted
技术标签:
【中文标题】ListView flutter 中如何管理不同小部件的状态?【英文标题】:How manage state of different widgets in ListView flutter? 【发布时间】:2022-01-17 13:42:17 【问题描述】:我正在构建一个 Flutter 应用程序,其中使用 ListView 显示列表。它返回一个带有用户信息的 ListTile。 ListTile
包含 leading
、title
和 subtitle
,其中 trailing
设置为 ElevatedButton
。
如下所示:
我想点击“邀请按钮”并更改 ListTile
中的 color
、text
和 subtitle
点击后应该是这个样子。
我该怎么做?这是我写的代码。但它正在改变每个列表项的状态。
class InviteFriends extends StatefulWidget
const InviteFriends(Key? key) : super(key: key);
@override
State<InviteFriends> createState() => _InviteFriendsState();
class _InviteFriendsState extends State<InviteFriends>
bool isSelected = false;
@override
void initState()
super.initState();
@override
void dispose()
super.dispose();
ListView.builder
下的UI:
ListTile(
title: const Text('Haris'),
subtitle: const Text(
isSelected ? 'Invitation Sent' : 'Not Invited Yet',
),
leading: CircleAvatar(
backgroundImage: NetworkImage(
_userProfile!.profilePhoto.toString(),
),
),
trailing: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.0,
primary: isSelected ? Colors.orange : Colors.green,
side: BorderSide.none,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
child: const Text(
isSelected ? 'Invited': 'Invite',
),
onPressed: ()
setState(()
isSelected = !isSelected;
);
,
),
);
我也在 ListTile 中使用 ValueKey(index)
尝试了 Keys,但它也没有工作。我该怎么办?谢谢
【问题讨论】:
【参考方案1】: return ListView.builder(
itemCount: itemCount.length
itemBuilder: (BuildContext context, int index)
return Friend(
//arg if available
);
);
class Friend extends StatefulWidget
const Friend(Key? key) : super(key: key);
@override
_FriendState createState() => _FriendState();
class _FriendState extends State<Friend>
bool isSelected = false;
@override
Widget build(BuildContext context)
//put ListTile detail here
return Row(
children: [
FlatButton(//deprecated but other buttons work
key: PageStorageKey('random num'),//if you are interested in keeping the state of the button while navigating
onPressed: ()
setState(()
isSelected = !isSelected;
);
,
child: Text(isSelected ? "INVITED" : "INVITE"))
],
);
【讨论】:
【参考方案2】:您创建一个列表,说“i”(变量)以了解每个图块的状态,并使用 false 进行初始化。点击时将状态更改为 true。
final List<bool> selected = List.generate(20, (i) => false);
将列表“i”传递给 listview.builder,例如:-
itemBuilder: (BuildContext context, i)
查看完整代码
import 'package:flutter/material.dart';
class InviteFriends extends StatefulWidget
const InviteFriends(Key? key) : super(key: key);
@override
State<InviteFriends> createState() => _InviteFriendsState();
class _InviteFriendsState extends State<InviteFriends>
bool isSelected = false;
@override
void initState()
super.initState();
@override
void dispose()
super.dispose();
final List<bool> selected = List.generate(20, (i) => false);
@override
Widget build(BuildContext context)
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(top: 60),
child: ListView.builder(
// itemCount: i,
itemBuilder: (BuildContext context, i)
return ListTile(
title: const Text('Haris'),
subtitle: Text(
selected[i] ? 'Invitation Sent' : 'Not Invited Yet',
),
leading: const CircleAvatar(
backgroundImage: AssetImage('assets/profile.gif'),
),
trailing: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.0,
primary: selected[i] ? Colors.orange : Colors.green,
side: BorderSide.none,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
child: Text(
selected[i] ? 'Invited' : 'Invite',
),
onPressed: ()
setState(() => selected[i] = !selected[i]);
// setState(()
// isSelected = !isSelected;
// );
),
);
),
),
);
谢谢
输出
【讨论】:
与使用单独的 Stateful Widget 有何不同。单独的小部件工作正常,但我不确定使用哪一个。有什么不同吗?【参考方案3】:您需要为 listtiles 创建不同的类。执行以下操作:
ListView.builder(
itemCount: 3,
shrinkWrap: true,
itemBuilder: (ctx, i)
return MyListItems();
))
然后是 MyListItems。
class MyListItems extends StatefulWidget
@override
MyListState createState() => MyListState();
class MyListState extends State<MyListItems>
bool isSelected = false;
@override
Widget build(BuildContext context)
return ListTile(
title: const Text('Haris'),
subtitle: Text(
isSelected ? "Invitation Sent" : 'Not Invited Yet',
),
leading: const CircleAvatar(
backgroundImage: NetworkImage(
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQYtfZRhbGQtq2BapB2MXJfWIO2QriO5Wx3qQ&usqp=CAU'),
),
// use your image here
trailing: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.0,
primary: isSelected ? Colors.orange : Colors.green,
side: BorderSide.none,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
child: Text(
isSelected ? 'Invited' : 'Invite',
),
onPressed: ()
setState(()
isSelected = !isSelected;
);
,
),
);
【讨论】:
【参考方案4】:将 Tile 作为单独的 StatefulWidget 取出,以便每个都有自己的状态。 不要修改 State List.builder。 并且你对所有 Tile 使用一个 isSelected 字段,你都会参考这个条件。
请提供更多代码,我可以提供帮助。以便我了解全貌
【讨论】:
以上是关于ListView flutter 中如何管理不同小部件的状态?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 的 ListView 中显示特定小部件的子小部件?