【问题标题】:Equivalent of viewWillAppear() in Flutter等效于 Flutter 中的 viewWillAppear()
【发布时间】:2019-06-09 02:27:57
【问题描述】:

我正在使用 Flutter 重建一个 iOS 应用程序,流程如下: 每次用户登陆主页时,都会从后端重新加载用户数据以检查是否有任何更改。

我在 Swift / iOS 中实现这一点的方法是使用 viewDidLoad() 函数。

我的 Flutter 代码是这样的:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  User user = User();

  @override
  void dispose() {
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    _fetchData(context);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        color: RColor.COLOR_main,
        child: Column(
          children: [
            Container(
              height: MediaQuery.of(context).size.height / 7,
              width: MediaQuery.of(context).size.width,
              padding: EdgeInsets.all(20),
              child: Container(
                child: Text("This is the homepage"),
                alignment: Alignment.bottomCenter,
              ),
            ),
          ],
        ));
  }

  Future _fetchData(BuildContext context) async {
    _fetchUserAPI(context);
  }

  Future _fetchUserAPI(BuildContext context) async {
    try {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      var accessToken = prefs.getString("access_token");
      var url = RConstants.API_BASE_URL + "/v1/users/self";
      Response response = await Dio()
          .get(url, options: Options(headers: {"Authorization": accessToken}));
      setState(() {
        user = User.fromJson(response.data);
      });
    } catch (e) {
      print(e.toString());
      Alert(
              context: context,
              title: "Something Went Wrong",
              desc: "Something went wrong while fetching your user data",
              type: AlertType.error)
          .show();
    }
  }
}

void initState() 但是,每次用户登陆主页时都不会触发。实现这一目标的正确方法是什么?

【问题讨论】:

  • 每次打开屏幕都会执行build方法
  • @diegoveloper 但这不是唯一一次。每次状态变化时都会触发
  • @Rutger,你能找到解决方案吗?
  • @Jan 彻底改变了应用程序的架构。转移到使用 BLoC 模式。我建议调查一下

标签: ios flutter dart


【解决方案1】:

嗯,这真的取决于你所说的“每次用户登陆主页”的确切含义。

如果用户通过Navigator.pushHomePage 导航到其他视图,然后通过Navigator.pop 返回,则HomePage 的状态保持不变,当然initState 方法不会触发。

如果您想在导航器中弹出其上方的路由时收到HomePage 的通知,那么您需要使用this 方法,覆盖它,然后在其中您将能够调用_fetchData()并更新主页的状态。

还有一件事:当你有一些像 _fetchData() 这样的异步调用时,只在 initState() 或任何其他框架方法中调用它是错误的模式。因为它将被调用,并且您状态的build() 方法几乎总是会在异步调用的结果返回之前立即被调用。处理这种情况的正确方法是使用FutureBuilder 小部件。

如果“每次用户登陆主页”意味着其他内容,例如应用程序在后台并被带到前台,或者当实现了对推送通知的支持并且用户单击通知并打开应用程序时 - 这种情况也可以处理,但这是一个更广泛的主题。

【讨论】:

    【解决方案2】:

    RouteAware 可以帮忙。

    1. 在 main.dart 中定义 final RouteObserver&lt;ModalRoute&lt;void&gt;&gt; routeObserver = RouteObserver&lt;ModalRoute&lt;void&gt;&gt;();
    2. 在 MaterialApp 函数中设置navigatorObservers: [ routeObserver ],
    3. 在需要实现viewWillAppear功能的页面中混入RouteAware
    4. 覆盖 didChangeDependenciesdidPopNext 方法并将此页面订阅到 routeObserver

    例如:

    main.dart

    final RouteObserver<ModalRoute<void>> routeObserver = RouteObserver<ModalRoute<void>>();
    void main() {
        runApp(MaterialApp(
            home: HomePage(),
            navigatorObservers: [ routeObserver ],
        ));
    }
    

    home_page.dart

    class _HomePageState extends State<HomePage> with RouteAware {
        @override
        void didChangeDependencies() {
            super.didChangeDependencies();
            routeObserver.subscribe(this, ModalRoute.of(context)!);
        }
    
        @override
        void dispose() {
            routeObserver.unsubscribe(this);
            super.dispose();
        }
    
        @override
        void didPopNext() {
            super.didPopNext();
            debugPrint("viewWillAppear");
        }
    }
    

    【讨论】:

    • 在构建 IconTheme(color: Color(0xdd000000)) 时引发了以下 _TypeError: type 'List' is not a subtype of type 'List>>' of '其他'
    • 使用 CupertinoApp 和 @SwiftiSwift 一样的错误
    • @swifthing 更新了答案以修复它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    相关资源
    最近更新 更多