Flutter使用StreamProvider设置状态

时间:2020-03-29 18:41:48

标签: flutter provider

我使用StreamProvider从本教程中进行了复制:https://github.com/iamshaunjp/flutter-firebase

我有一个单独的课程,像这样:

class PostItem extends StatefulWidget {
  PostItem({Key key, @required this.post}) : super(key: key);

  final Post post;

  @override
  _PostItemState createState() => _PostItemState();
}

class _PostItemState extends State<PostItem> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return getCard(context);
  }

  Widget getCard(context) {
    return Card(
      child: InkWell(
        onTap: _didSelectItem,
        child: Row(
          children: [
            _textColumn(context),
            _voteColumn(context),
          ],
        ),
      ),
    );
  }

  Widget _textColumn(context) {
    return Expanded(
      child: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
              child: Text(
                widget.post.title,
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
              ),
              padding: const EdgeInsets.fromLTRB(16, 16, 0, 0),
            ),
            BottomButtonBar(
              onLikedPressed: () => _didLikePost(),
              // likeColor: _likedPids.contains(widget.post.pid)
              //     ? Theme.of(context).primaryColor
              //     : Theme.of(context).accentColor,
            ),
          ],
        ),
      ),
    );
  }

  Widget _voteColumn(context) {
    final user = Provider.of<User>(context);
    final post = widget.post;

    return VoteColumn(
        upArrowColor:
            Vote.getVote(user.uid, post.upvoteUids, post.downvoteUids) ==
                    Vote.up
                ? Theme.of(context).primaryColor
                : Theme.of(context).focusColor,
        downArrowColor:
            Vote.getVote(user.uid, post.upvoteUids, post.downvoteUids) ==
                    Vote.down
                ? Theme.of(context).primaryColor
                : Theme.of(context).focusColor,
        didVote: (val) => _didVote(val),
        value: widget.post.upvoteUids.length - widget.post.downvoteUids.length);
  }

  //Mark: Private
  _didLikePost() {
    print("called");
    setState(() {});
    // _dbLikePost();
  }

  _dbLikePost() async {
    // final userMetadata = Provider.of<UserMetadata>(context);
    // try {
    //   Database().updateUserMetadata(userMetadata);
    // } catch (error) {
    //   print(error);
    // } finally {}
  }

  _didSelectItem() {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (BuildContext context) => Comments(post: widget.post),
      ),
    );
  }

  //true for up, false for down
  _didVote(bool newVote) {
    setState(() {
      _locatUpdate(newVote);
    });
    _dbUpdate();
  }

  _locatUpdate(newVote) {
    final user = Provider.of<User>(context);
    final uid = user.uid;
    final post = widget.post;
    switch (Vote.getVote(user.uid, post.upvoteUids, post.downvoteUids)) {
      case Vote.up:
        if (newVote) {
          post.upvoteUids.remove(uid);
        } else {
          post.upvoteUids.remove(uid);
          post.downvoteUids.add(uid);
        }
        break;
      case Vote.down:
        if (newVote) {
          post.downvoteUids.remove(uid);
          post.upvoteUids.add(uid);
        } else {
          post.downvoteUids.remove(uid);
        }
        break;
      case Vote.none:
        if (newVote) {
          post.upvoteUids.add(uid);
        } else {
          post.downvoteUids.add(uid);
        }
        break;
    }
  }

  _dbUpdate() async {
    try {
      await Database().post(widget.post);
    } catch (error) {
      print(error);
    } finally {}
  }
}

在这里,我感到非常困惑。我可以更改widget.post并调用setState,它可以完美运行。我还可以使用widget.post更新数据库中的帖子。如我所料,效果很好。

现在,我想更新已放在上面流中的userMetadata。

 Widget build(BuildContext context) {
    final user = Provider.of<User>(context);

    return user == null
        ? MaterialWidget(home: AuthView())
        : StreamProvider<UserMetadata>.value(
            value: Database(id: user.uid).userMetadata,
            catchError: (_, error) => UserMetadata(uid: ""),
            child: MaterialWidget(
              home: Home(
                title: "Siren",
              ),
            ),
          );
  }

我只想设置PostItem页面的状态,并在单击like按钮时更改db。我想使用流提供程序中的UserMeta来执行此操作。但是,如果尝试执行此操作,则会收到错误消息“不支持的操作:无法添加到无法修改的列表”。为什么在尝试编辑流提供程序时却出现此错误,而对于帖子却没有?编辑列表,将setState设置到位然后推送到数据库的正确方法是什么?

0 个答案:

没有答案