如何在Flutter中唯一标识小部件?

4
当从ListView中轻敲特定的小部件时,该功能是显示用户的个人资料屏幕。 我希望将每个小部件分配唯一的ID,并通过循环遍历创建小部件。 然后,我将创建的小部件添加到一个列表中,并将该列表放入ListView中。 在应用程序中正确构建ListView,但我不知道如何将唯一ID添加到ListView中的小部件中,以便在轻敲小部件时,检索该小部件ID的个人资料并在新屏幕中显示。
我可能对解决此问题的方法有误解。否则,当用户使用它时,ID将呈现在应用程序中,这可能会导致漏洞问题。
我尝试使用widgets的key属性存储用户唯一ID。我还搜索了网络,是否有一种将唯一ID分配给小部件的方法,但没有成功,或者我没有找到正确的方法。
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();
    }
  }
}

预期结果是当小部件被点击时,打开用户的个人资料新屏幕,并显示相应的用户ID。
2个回答

2
我认为您不需要识别小部件。相反,您可以在onTap闭包中使用用户ID。
这是更新后的_createFriendListWidget的样子:
  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);
  }

请注意,我已经删除了Column,因为它只有一个子元素,所以没有任何效果。并且我删除了Inkwell,因为ListView也可以处理onTap

最初的回答:

注意,我移除了Column,因为它仅有一个子节点,所以不会产生任何影响。我还移除了Inkwell,因为ListView也可以处理onTap事件。


我已经按照您建议的更改了_createFriendListWidget函数,现在它运行得很好!谢谢!当我实现从后端检索数据的功能时,它完美地工作。 - Elonas Marcauskas
很遗憾,这并没有回答标题中的问题... - TOPKAT

0
你可以将列表中的用户输入(Card)提取到自定义小部件中。然后,您可以添加和使用任何自定义字段,包括标识符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接