Flutter Navigator.push -> 第二页没有用新值刷新状态。

问题描述 投票:0回答:1

我的应用中有一个简单的帖子模块,在帖子概览和帖子详情页上显示 "心"。在这两个页面上,用户可以 "心动 "一个帖子,这样做会将用户ID写回火库文档,并增加整体的心动计数器。

问题是,如果帖子在概览页上被心动,然后用户导航到详情页,新的计数和新的 "心动 "状态没有显示。似乎是导航到下一个页面后没有新设置状态。变量似乎是正确的,因为我用各种打印语句测试过。一旦我再次手动点选 "心",就会显示出正确的计数器和 "心 "的状态。

因此,我如何才能在导航仪.推送命令后强制设置状态?

从第一页开始导航。

GestureDetector(
      onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => new PostPage(postData: widget.postData)));
      }, [...] )

Hearts组件--单独的.dart文件,被包含在post overview和post detail页面中。

class _PostStatsState extends State<PostStats> {

  var _heartsIcon = Icons.favorite;
  dynamic _hearts = -1;
  dynamic _setState = false;

  Future<String> getUserId() async {
      final prefs = await SharedPreferences.getInstance();
      return prefs.getString('userId');
  }

  @override
  Widget build(BuildContext context) {

    final PostModel postData = InheritedPostModel.of(context).postData;

    void setHeartsIcon()async{
      final userId = await getUserId();
      if (postData.heartedBy.contains(userId)) {
        _heartsIcon = Icons.favorite;
      }
      else {
        _heartsIcon = Icons.favorite_border;
      }
    }
      _hearts = widget.hearts;
      setHeartsIcon();
      print("!Set $_hearts $_heartsIcon"); // correct number and icon are printed
[...]

小部件组件。 小部件组件:/不显示与上面打印的相同的数字和图标。

[...]

_showStat(
            _heartsIcon,
            _hearts,
            Colors.red[300],
            _heartOrUnheart
            ),
[...]

小工具

Widget _showStat(IconData icon, int number,Color color, Function buttonAction) {
    return Column(
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.only(right: 2.0),
          child: IconButton(icon: Icon(icon), color: color,  onPressed: buttonAction,
          enableFeedback: true,),
        ),
        Text(number.toString()),
      ],
    );
  }

我找来找去,花了太多的时间来解决这个问题,却没有任何收获。希望有人有一个简单的解决方案。

flutter state reset navigator
1个回答
1
投票

你可以在initState中设置数据,但你使用的是InheritedWidgets,所以你应该像这样在didChangeDependencies中设置。

class _PostStatsState extends State<PostStats> {
  var _heartsIcon = Icons.favorite;
  dynamic _hearts = -1;
  dynamic _setState = false;

  Future<String> getUserId() async {
     final prefs = await SharedPreferences.getInstance();
     return prefs.getString('userId');
  }

  void setHeartsIcon(PostModel postData)async{
    final userId = await getUserId();
    if (postData.heartedBy.contains(userId)) {
      _heartsIcon = Icons.favorite;
    }
    else {
      _heartsIcon = Icons.favorite_border;
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final PostModel postData = InheritedPostModel.of(context).postData;
    _hearts = widget.hearts;
    setHeartsIcon(postData);
    print("!Set $_hearts $_heartsIcon");
  }

  @override
  Widget build(BuildContext context) {

  [....]

尽量保持你的构建方法的干净。

如果你没有使用 Inhertied widget,你可以采用另一种方法,将前一个页面的数据传递到这个页面,并在 initState 中设置它。


0
投票
  @override
  Widget build(BuildContext context) {

    return FutureBuilder<void>(
        future: _setHeartsIcon(), // async work
        builder: (context, snapshot) {
           if (snapshot.connectionState == ConnectionState.done) {
            return _showStats();
          }
          else {
            // Otherwise, display a loading indicator.
            return _showStats();
          }
         },
    );
  }

这可能不是最干净的代码,但它确保在所有数据被加载后,_showStats()会被再次调用。由于数据只从SharedPreferences异步拉取,这似乎是一个毫秒的问题,在UI上并不可见。

© www.soinside.com 2019 - 2024. All rights reserved.