如何唯一地识别flutter中的小部件?

时间:2019-07-29 00:57:16

标签: firebase listview flutter dart widget

此功能是当从ListView轻按特定的窗口小部件时显示用户的个人资料屏幕。我要为每个窗口小部件分配唯一ID的方式是从Firebase作为数组检索所有ID,然后通过循环for循环来创建窗口小部件。然后,将创建的小部件添加到列表中,然后将该列表放入ListView中。 ListView可在应用程序中正确构建,但我不知道如何向ListView中的小部件添加唯一ID,以便在点击它们时检索该小部件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轻敲窗口小部件时,打开用户个人资料的新屏幕。

1 个答案:

答案 0 :(得分:0)

我认为您不需要识别小部件。相反,您可以在const foo = await bar.$eval('.foo', (el => el.textContent)); 闭包中使用用户ID

onTap的外观如下:

_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