每当页面出现在屏幕上时如何重新加载页面 - flutter

Bal*_*ala 7 dart flutter flutter-layout

每次页面在屏幕上可见时,flutter 中是否有可用的回调?在 ios 中有一些委托方法,如viewWillAppear, viewDidAppear, viewDidload

每当屏幕上显示特定页面时,我想调用 API 调用。

注意:我不是在询问应用程序状态,例如前景、背景、暂停、恢复。

谢谢你!

Bla*_*nka 8

具体到你的问题:

使用initState但请注意,您不能使用asynccall in,initState因为它在初始化小部件之前调用,正如名称的含义。如果你想在创建 UI 之后做点什么,那didChangeDependencies很好。但切勿在build()不使用FutureBuilder或不使用的情况下使用StreamBuilder

演示的简单示例:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(MaterialApp(home: ExampleScreen()));
}

class ExampleScreen extends StatefulWidget {
  ExampleScreen({Key key}) : super(key: key);

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

class _ExampleScreenState extends State<ExampleScreen> {
  List data = [];
  bool isLoading = true;

  void fetchData() async {
    final res = await http.get("https://jsonplaceholder.typicode.com/users");
    data = json.decode(res.body);
    setState(() => isLoading = false);
  }

  // this method invokes only when new route push to navigator
  @override
  void initState() {
    super.initState();
    fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: isLoading
            ? CircularProgressIndicator()
            : Text(data?.toString() ?? ""),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

StatefulWidgetState类的一些生命周期方法:

initState()

描述由此小部件表示的用户界面部分。

框架在多种不同情况下调用此方法:

After calling initState.
After calling didUpdateWidget.
After receiving a call to setState.
After a dependency of this State object changes (e.g., an InheritedWidget referenced by the previous build changes).
After calling deactivate and then reinserting the State object into the tree at another location.
Run Code Online (Sandbox Code Playgroud)

框架使用此方法返回的小部件替换此小部件下方的子树,通过更新现有子树或删除子树并膨胀新子树,取决于此方法返回的小部件是否可以更新现有子树的根,通过调用 Widget.canUpdate 确定。 阅读更多

didChangeDependencies()

当此 State 对象的依赖项更改时调用。

例如,如果先前对 build 的调用引用了后来更改的 InheritedWidget,则框架将调用此方法来通知此对象有关更改的信息。

此方法也会在 之后立即调用initState。打电话是安全的BuildContextdependOnInheritedWidgetOfExactType从这个方法。 阅读更多

build() (无状态小部件)

描述由此小部件表示的用户界面部分。

当这个小部件被插入到给定 BuildContext 中的树中并且当这个小部件的依赖关系改变(例如,InheritedWidget这个小部件引用的一个改变)时,框架调用这个方法。 阅读更多

didUpdateWidget(Widget oldWidget)

每当小部件配置更改时调用。

如果父小部件重建并请求树中的此位置更新以显示具有相同 runtimeType 和 的新小部件 Widget.key,则框架将更新此State对象的小部件属性 以引用新小部件,然后使用前一个小部件调用此方法作为论据。 阅读更多


Doc*_*Doc 6

您不需要StatefulWidget每次显示屏幕时都调用 api。

在以下示例代码中,按浮动操作按钮导航到 api 调用屏幕,使用后退箭头返回,再次按浮动操作按钮导航到 api 页面。

每次访问此页面时都会自动调用 api。

import 'dart:async';

import 'package:flutter/material.dart';

main() => runApp(MaterialApp(home: HomePage()));

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      floatingActionButton: FloatingActionButton(
        onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => ApiCaller())),
      ),
    );
  }
}

class ApiCaller extends StatelessWidget {
  static int counter = 0;

  Future<String> apiCallLogic() async {
    print("Api Called ${++counter} time(s)");
    await Future.delayed(Duration(seconds: 2));
    return Future.value("Hello World");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Api Call Count: $counter'),
      ),
      body: FutureBuilder(
        future: apiCallLogic(),
        builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) return const CircularProgressIndicator();

          if (snapshot.hasData)
            return Text('${snapshot.data}');
          else
            return const Text('Some error happened');
        },
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这是零样板代码的简单代码。


Fro*_*and 5

有些小部件是无状态的,有些是有状态的。如果它是无状态小部件,则只有值可以更改,但不会呈现 UI 更改。

有状态小部件的方式相同,它的值和 UI 都会发生变化。

现在,将研究方法。

  1. initState():这是在创建小部件时但在构造函数调用之后调用的第一个方法。

@override
void initState() {
   // TODO: implement initState
   super.initState();
}
Run Code Online (Sandbox Code Playgroud)
  1. didChangeDependecies() - 当这个 State 对象的依赖改变时调用。在 initState 方法之后立即调用。

@override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }
Run Code Online (Sandbox Code Playgroud)
  1. didUpdateWidget() - 每当小部件配置更改时都会调用它。框架总是在 didUpdateWidget 之后调用 build

@override
void didUpdateWidget (
   covariant Scaffold oldWidget
)
Run Code Online (Sandbox Code Playgroud)
  1. setState() - 每当 State 对象的内部状态想要改变时,都需要在 setState 方法中调用它。

 setState(() {});
Run Code Online (Sandbox Code Playgroud)
  1. dispose() - 当这个对象从树中永久移除时调用。

@override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }
Run Code Online (Sandbox Code Playgroud)