Reputation: 361
The feature is to display the profile screen of a user when a specific widget is tapped from a ListView. The way I want to assign each widget with unique ID is to retrieve all IDs from Firebase as an array and create the widgets by iterating through a for loop. Then I add the created widgets to a list and put that list into a ListView. The ListView builds correctly in the application, but I do not know how to add the unique ID's to the widgets in the ListView so that when they are tapped the profile of that widget's ID is retrieve and displayed in a new screen.
I may have the wrong idea about approaching this problem. Because otherwise the IDs will be rendered into the application when the user is using it, which may cause vulnerability issues.
I have tried to use the key property of widgets to store the user unique ID. I also searched the web if there is a way to assign an unique ID to a widget but no luck, or I jam not searching the right way.
enum ScreenStatus {
NOT_DETERMINED,
RETRIEVING_FRIEND_LIST,
FRIEND_LIST_READY,
FRIEND_PROFILE_OPEN
}
class FriendsScreen extends StatefulWidget {
FriendsScreen({this.auth});
final BaseAuth auth;
@override
State<StatefulWidget> createState() => _FriendsScreenState();
}
class _FriendsScreenState extends State<FriendsScreen> {
ScreenStatus screenStatus = ScreenStatus.NOT_DETERMINED;
List _friendList = [];
@override
void initState() {
super.initState();
widget.auth.retrieveUserDocument().then((document) {
document.data.forEach((fieldName, fieldValue) {
setState(() {
if (fieldName == 'friends') {
_friendList = fieldValue;
print(_friendList);
}
screenStatus = _friendList == null
? ScreenStatus.RETRIEVING_FRIEND_LIST
: ScreenStatus.FRIEND_LIST_READY;
});
});
});
}
Widget _createFriendListWidget(List friendList) {
List<Widget> list = List<Widget>();
for (int i = 0; i < friendList.length; i++) {
list.add(
Card(
child: InkWell(
onTap: () {
print('tapped');
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.album),
title: Text(friendList[i]),
subtitle: Text('Subtitle'),
)
],
),
),
),
);
}
return ListView(children: list);
}
Widget _buildFriendList() {
return Scaffold(
body: Container(
child: _createFriendListWidget(_friendList),
),
);
}
Widget _buildWaitingScreen() {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);
;
}
@override
Widget build(BuildContext context) {
switch (screenStatus) {
case ScreenStatus.NOT_DETERMINED:
return _buildWaitingScreen();
break;
case ScreenStatus.RETRIEVING_FRIEND_LIST:
return _buildWaitingScreen();
break;
case ScreenStatus.FRIEND_LIST_READY:
return _buildFriendList();
break;
default:
return _buildWaitingScreen();
}
}
}
The expected result is to open a new screen of the profile of the user when the widget is tapped with the respective ID of the user.
Upvotes: 4
Views: 8015
Reputation: 11
You may extract user entry (Card
) in the list into custom widget. You can then add and use any custom field with it, including identifier.
Upvotes: 0
Reputation: 2711
I don't think you need to identify widgets. Instead you can use user id in onTap
closure
Here is how updated _createFriendListWidget
could look:
Widget _createFriendListWidget(List friendList) {
List<Widget> list = List<Widget>();
for (int i = 0; i < friendList.length; i++) {
list.add(
Card(
child: ListTile(
leading: Icon(Icons.album),
title: Text(friendList[i]),
subtitle: Text('Subtitle'),
onTap: () {
print("tapped ${friendList[i].id}"); // assume that id is in .id field
}
),
),
);
}
return ListView(children: list);
}
Also note that I've removed Column
, because it had only one child so it did not have any effect. And I removed Inkwell
because ListView
can handle onTap
too.
Upvotes: 2