flutter从外部调用setState()

一般来说,flutter中StatefulWidget里的setState()方法只能在State类中调用,这篇文章介绍了如何从外部调用setState()方法。

需要调用setState()的场合多半是因为页面上的某些元素需要更新,比如用户在登陆后”我的“页面中需要显示用户名,但是登陆表单肯定不在”我的“页面中,甚至可能不是由”我的“页面打开的;那么我们就需要在登陆成功后主动通知”我的“页面去更新显示的用户名。

有人可能会说不是有生命周期函数吗,肯定有更优雅和自动化的实现方式,但有些情况下生命周期函数是不会按照官方文档中的被调用的,这个我们下篇博客中再详细说明。

  1. 首先在State类中写一个函数,完成界面更新的任务,比如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    updateUsername() {
    SharedPreferences.getInstance().then((prefs) {
    final isLogin = (prefs.getBool('isLogin') ?? false);
    setState(() {
    if (isLogin) {
    username = prefs.getString('username')!;
    } else {
    username = "请登录";
    }
    });
    });
    }
  2. 然后对StatefulWidget类进行改造,原先是这个样子:

    1
    2
    3
    4
    5
    6
    class ClassName extends StatefulWidget {
    const ({Key? key}) : super(key: key);

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

    我们要把它改造成这个样子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MyInfo extends StatefulWidget {
    static final _MyInfoState _myInfoState = _MyInfoState();

    @override
    _MyInfoState createState() => __myInfoState;

    static void updateUsername() {
    _myInfoState.updateUsername();
    }
    }

    可以看到,我们删除了无用的super,将原先匿名的_State类改为了私有变量,并且定义了一个static的方法,这个方法的唯一作用就是去调用_State类那个实例中的同名方法。

  3. 这样之后,从外部就可以调用MyInfo.updateUsername()以完成界面更新了。