【问题标题】:Future Builder not building未来的建造者没有建造
【发布时间】:2021-01-03 21:02:30
【问题描述】:

我正在尝试包含FutureBuilder,但它进入CircularProgressIndicator(),并且在通过调用SharedPreferences 填充“时间”的值并且ConnectionState 是@987654324 之后不会加载实际的屏幕代码@。它只是卡在 CircularProgressIndicator() 中。

我在这里错过了什么?

Future<int> getTime() async {
  await MySharedPreferences.instance.getIntValue("time_key").then((value) =>
    setState(() {
     time= value;
}));
     return time;
        

      @override
 void initState() {
super.initState();

MySharedPreferences.instance
    .getStringValue("title_key")
    .then((value) => setState(() {
  title = value;
}));



controller =
    AnimationController(vsync: this,
        duration: Duration(
            seconds: time));
controller2 =
    AnimationController(vsync: this,
        duration: Duration(
            seconds: time));
controller3 =
    AnimationController(vsync: this,
        duration: Duration(
            seconds: 1));
    ....}
      
@override
Widget build(BuildContext context){

            return WillPopScope(

              onWillPop: () async => false,
              child: Scaffold(

                backgroundColor: Colors.black,
                body: FutureBuilder<int>
                  (
                  future: getTime(),
                builder: ( BuildContext context, AsyncSnapshot<int> snapshot) {
                  print(snapshot);
                  print(time);
                  if (snapshot.connectionState == ConnectionState.done) {
                    print(time);
                    return SafeArea(

                      minimum: const EdgeInsets.all(20.0),
                      child: Stack(
                        children: <Widget>[
                          Container(
                            child:
                            Align(
                              alignment: FractionalOffset.topCenter,
                              child: AspectRatio(
                                aspectRatio: 1.0,
                                child: Container(
                                  height: MediaQuery
                                      .of(context)
                                      .size
                                      .height / 2,
                                  width: MediaQuery
                                      .of(context)
                                      .size
                                      .height / 2,
                                  decoration: BoxDecoration(
                                    //shape: BoxShape.rectangle,
                                      color: Colors.black,
                                      image: DecorationImage(

                                        image: AssetImage(
                                            "assets/images/moon.png"),
                                        fit: BoxFit.fill,
                                      )
                                  ),
                                ),
                              ),
                            ),
                          ),
                          build_animation(),
                          

                        ],
                      ),
                    );
                  }


                  else {
                    return CircularProgressIndicator();
                  }
                }


                  ),
  ),
            );
        }


build_animation() {
  return AnimatedBuilder(
      animation: controller,
      builder: (context, child) {
        return Stack(
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(0.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Expanded(
                    child: Align(
                      alignment: FractionalOffset.bottomCenter,
                      child: AspectRatio(
                        aspectRatio: 1.0,
                        child: Stack(
                          children: <Widget>[
                            Padding(
                              padding: EdgeInsets.only(top:MediaQuery.of(context).size.height / 6),
                              child: Column(
                                children: <Widget>[

                                  Text(
                                    title.toString(),
                                    style: TextStyle(
                                      fontSize: 20.0,
                                      color: Colors.black,fontWeight: FontWeight.bold,),
                                  ),
                                  new Container(
                                    child: new Center(
                                      child: new Countdown(
                                        animation: new StepTween(
                                          begin: time,
                                          end: 0,
                                        ).animate(controller),
         .....

【问题讨论】:

  • 当我看到代码 FutureBuilder 构建甚至多次,在 print(snapshot) 之前添加 print(snapshot) - 你在日志上看到了什么?
  • 它连续打印以下消息:flutter: AsyncSnapshot(ConnectionState.waiting, 17, null) 。为什么卡在等待状态?我做错了吗: Future getTime() async { await MySharedPreferences.instance.getIntValue("time_key").then((value) => setState(() { time= value; }));返回时间;我需要共享首选项中的“时间”值(一个整数)。该值用于构建中动画控制器的持续时间。
  • Future&lt;int&gt; getTime() =&gt; MySharedPreferences.instance.getIntValue("time_key")
  • 是的,这解决了 ConnectionState.waiting 问题,但它不会将时间值更新为从共享首选项中获得的值。有什么想法吗?
  • 您在以后发布的构建器代码中没有使用time 变量

标签: flutter sharedpreferences flutter-futurebuilder


【解决方案1】:

对于初学者,您不需要 setState 来获取与 FutureBuilder 一起使用的 Future 的结果。 FutureBuilder 类的全部意义在于为您处理。此外,在您有更多经验之前,最好不要混合使用.then()await。它们可以很好地协同工作,但在您仍在学习时一次只专注于一个概念。

这是你精简后的方法(你的选择是否仍然值得一个方法,或者如果你想将该代码直接放入iniState):

 Future<int> getTime() async {
    final value = await MySharedPreferences.instance.getIntValue("time_key");
    return value;
 }

您应该将该方法提供给您的 FutureBuilder,否则您将在每次调用 build 时重新启动它。

所以你initState 应该是这样的:

Future<int> futureIntFromPreferences;

@override
void initState() {
  super.initState();

  futureIntFromPreferences = getTime();
}

然后你可以在你的FutureBuilder 中使用它:

body: FutureBuilder<int>(
        future: futureIntFromPreferences,
        builder: (BuildContext context, AsyncSnapshot<int> snapshot) {

详细解释请阅读What is a Future and how do I use it?

【讨论】:

  • 谢谢...您的解释使事情更容易理解。但是,我仍然无法更新“时间”变量的值(对于动画控制器)。是否允许使用 Future Builder 更新控制器持续时间值?
猜你喜欢
  • 2020-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多