【问题标题】:How to uniquely identify widgets in flutter?如何唯一标识flutter中的小部件?
【发布时间】:2019-12-06 08:04:57
【问题描述】:

该功能是在从 ListView 中点击特定小部件时显示用户的个人资料屏幕。我想为每个小部件分配唯一 ID 的方式是从 Firebase 中检索所有 ID 作为数组,并通过迭代 for 循环来创建小部件。然后我将创建的小部件添加到列表中,并将该列表放入 ListView。 ListView 在应用程序中正确构建,但我不知道如何将唯一 ID 添加到 ListView 中的小部件,以便在点击它们时检索该小部件 ID 的配置文件并将其显示在新屏幕中。

我可能对解决这个问题有错误的想法。因为否则在用户使用时ID会被渲染到应用程序中,这可能会导致漏洞问题。

我尝试使用小部件的 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 轻按小部件时,会打开用户个人资料的新屏幕。

【问题讨论】:

    标签: firebase listview flutter dart widget


    【解决方案1】:

    我认为您不需要识别小部件。相反,您可以在 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

    【讨论】:

    • 在我的 _createFriendListWidget 函数中实现了您建议更改的内容,效果很好!谢谢!当我实现从后端检索数据的功能时,它可以完美运行。
    • 太糟糕了,这并没有回答标题中的问题......
    猜你喜欢
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 2021-12-09
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多