【问题标题】:FutureBuilder<dynamic> inside CustomScrollView flutterCustomScrollView 中的 FutureBuilder<dynamic> 颤动
【发布时间】:2020-10-07 09:52:28
【问题描述】:

您好,我想设计一个页面,该页面应该垂直滚动并且应该有 GridView.builder。我正在访问服务器以加载数据,如果数据处于共享首选项中,那么我将从共享首选项中获取它。对于 GridView.builder,我使用 FutureBuilder 加载数据。但我得到的错误是错误

'owner._debugCurrentBuildTarget == this': 不正确

下面是代码。

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // Initialize without device test ids
  Admob.initialize();
  // Add a list of test ids.
  // Admob.initialize(testDeviceIds: ['YOUR DEVICE ID']);

  runApp(FirstScreen());
}

class FirstScreen extends StatefulWidget {
  @override
  _CrosspromoPageState createState() => _CrosspromoPageState();
}

class _CrosspromoPageState extends State<FirstScreen> {
  AdmobInterstitial interstitialAd;
  List<CrosspromotionPojo> crosspromoobject = List();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // getCrosspromodata();
    // loadcrossPromodata();
    interstitialAd = AdmobInterstitial(
      adUnitId: getInterstitialAdUnitId(),
      listener: (AdmobAdEvent event, Map<String, dynamic> args) {
        if (event == AdmobAdEvent.closed) interstitialAd.load();
      },
    );
    interstitialAd.load();
  }

  String getInterstitialAdUnitId() {
    if (Platform.isIOS) {
      return 'ca-app-pub-3940256099942544/4411468910';
    } else if (Platform.isAndroid) {
      return 'ca-app-pub-3940256099942544/1033173712';
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    SizeConfig().init(context);
    return Scaffold(
      body: Container(
        child: CustomScrollView(
          slivers: <Widget>[
            new Image.asset('assets/images/bg_half_image.jpg'),
            new Align(
                alignment: Alignment.topCenter,
                child: new Container(
                  margin: EdgeInsets.fromLTRB(0, 55, 0, 0),
                  width: 150,
                  height: 150,
                  child: Image.asset('assets/images/logo.png'),
                )),
            new Align(
                alignment: Alignment.topCenter,
                child: InkWell(
                    onTap: () async {
                      if (await interstitialAd.isLoaded) {
                        interstitialAd.show();
                      }
                      int val = await DatabaseHelper.instance.queryRowCount();
                      if (val == 0) {
                        DatabaseHelper.instance.insertExcdaydata();
                        DatabaseHelper.instance.insertExcdaydatainapp();
                      } else
                        Navigator.pop(context, true);
                      {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => BannerPage(),
                          ),
                        );
                      }
                    },
                    child: new Container(
                      width: 150,
                      margin: EdgeInsets.fromLTRB(0, 200, 0, 0),
                      //padding: EdgeInsets.fromLTRB(4, 0, 4, 4),
                      child: new Image.asset('assets/images/start.png'),
                    ))),
            new Container(
              alignment: Alignment.topCenter,
              margin: EdgeInsets.only(
                  left: 0,
                  right: 0,
                  top: SizeConfig.screenHeight / 1.8,
                  bottom: 0),
              child: Text("TRY OUR NEW APPS",
                  style: TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.bold,
                      fontSize: 20)),
            ),
            new FutureBuilder<dynamic>(
                future: getCrosspromodata(),
                builder:
                    (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Center(child: Text('Please wait its loading...'));
                  } else {
                    return Container(
                      margin: EdgeInsets.only(
                          left: 0,
                          right: 0,
                          top: SizeConfig.screenHeight / 1.6,
                          bottom: 0),
                      child: Align(
                        child: GridView.builder(
                          itemCount: crosspromoobject.length,
                          itemBuilder: (context, index) => GestureDetector(
                            onTap: () => tapped(index),
                            child: Container(
                                child: new Card(
                              elevation: 2,
                              child: Column(
                                children: <Widget>[
                                  new Container(
                                    child: CachedNetworkImage(
                                      imageUrl: crosspromoobject[index].appUrl,
                                      placeholder: (context, url) =>
                                          CircularProgressIndicator(),
                                      errorWidget: (context, url, error) =>
                                          Icon(Icons.error),
                                    ),
                                  ),
                                  new Container(
                                      alignment:
                                          AlignmentDirectional.centerStart,
                                      child: Text(
                                        crosspromoobject[index].app_name,
                                        style: TextStyle(
                                            color: Colors.black, fontSize: 15),
                                      ))
                                ],
                              ),
                            )),
                          ),
                          gridDelegate:
                              SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 3,
                            mainAxisSpacing: 30,
                            crossAxisSpacing: 15,
                            childAspectRatio:
                                MediaQuery.of(context).size.width /
                                    (MediaQuery.of(context).size.height / 1.1),
                          ),
                        ),
                      ),
                    );
                  }
                })
          ],
        ),
      ),
    );
    /*return Scaffold(
        body: Scaffold(
            body: Stack(
      children: [
        new Image.asset('assets/images/bg_half_image.jpg'),
        new Align(
            alignment: Alignment.topCenter,
            child: new Container(
              margin: EdgeInsets.fromLTRB(0, 55, 0, 0),
              width: 150,
              height: 150,
              child: Image.asset('assets/images/logo.png'),
            )),
        new Align(
            alignment: Alignment.topCenter,
            child: InkWell(
                onTap: () async {
                  if (await interstitialAd.isLoaded) {
                    interstitialAd.show();
                  }
                  int val = await DatabaseHelper.instance.queryRowCount();
                  if (val == 0) {
                    DatabaseHelper.instance.insertExcdaydata();
                    DatabaseHelper.instance.insertExcdaydatainapp();
                  } else
                    Navigator.pop(context, true);
                  {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => BannerPage(),
                      ),
                    );
                  }
                },
                child: new Container(
                  width: 150,
                  margin: EdgeInsets.fromLTRB(0, 200, 0, 0),
                  //padding: EdgeInsets.fromLTRB(4, 0, 4, 4),
                  child: new Image.asset('assets/images/start.png'),
                ))),
        new Container(
          alignment: Alignment.topCenter,
          margin: EdgeInsets.only(
              left: 0, right: 0, top: SizeConfig.screenHeight / 1.8, bottom: 0),
          child: Text("TRY OUR NEW APPS",
              style: TextStyle(
                  color: Colors.black,
                  fontWeight: FontWeight.bold,
                  fontSize: 20)),
        ),
        new FutureBuilder<dynamic>(
            future: getCrosspromodata(),
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return Center(child: Text('Please wait its loading...'));
              } else {
                return Container(
                  margin: EdgeInsets.only(
                      left: 0,
                      right: 0,
                      top: SizeConfig.screenHeight / 1.6,
                      bottom: 0),
                  child: Align(
                    child: GridView.builder(
                      itemCount: crosspromoobject.length,
                      itemBuilder: (context, index) => GestureDetector(
                        onTap: () => tapped(index),
                        child: Container(
                            child: new Card(
                          elevation: 2,
                          child: Column(
                            children: <Widget>[
                              new Container(
                                child: CachedNetworkImage(
                                  imageUrl: crosspromoobject[index].appUrl,
                                  placeholder: (context, url) =>
                                      CircularProgressIndicator(),
                                  errorWidget: (context, url, error) =>
                                      Icon(Icons.error),
                                ),
                              ),
                              new Container(
                                alignment: AlignmentDirectional.centerStart,
                                  child: Text(
                                crosspromoobject[index].app_name,
                                style: TextStyle(
                                    color: Colors.black, fontSize: 15),
                              ))
                            ],
                          ),
                        )),
                      ),
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 3,
                        mainAxisSpacing: 30,
                        crossAxisSpacing: 15,
                        childAspectRatio: MediaQuery.of(context).size.width /
                            (MediaQuery.of(context).size.height / 1.1),
                      ),
                    ),
                  ),
                );
              }
            })
      ],
    )))*/
  }

  Future<dynamic> loadcrossPromodata() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    List<dynamic> tagObjsJson =
        (json.decode(pref.getString('userData')) ?? List<dynamic>());
    crosspromoobject = tagObjsJson
        .map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
        .toList();
    return tagObjsJson;
  }

  Future<dynamic> getCrosspromodata() async {
    List<dynamic> tagObjsJson;
    SharedPreferences pref = await SharedPreferences.getInstance();
    try {
      Response<Map> versionresponse = await Dio().get(
          "https://videomergerapp.com/mobilestores/https/cross_promo_photoapps/verison.json");
      Map arrayObjresponse = versionresponse.data;
      int version = arrayObjresponse['healthw_version'];
      int localversion = pref.getInt('local_version') ?? 0;
      if (version > localversion) {
        Response<Map> response = await Dio().get(
            "https://videomergerapp.com/mobilestores/https/cross_promo_fitness/cross_promo_health_fitness_firstscreen.json");
        String arrayObjsText = response.toString();
        tagObjsJson = jsonDecode(arrayObjsText)['item_array'] as List;
        crosspromoobject = tagObjsJson
            .map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
            .toList();
        savePojo(tagObjsJson);
        pref.setInt('local_version', version);
        return tagObjsJson;
      } else {
        loadcrossPromodata();
      }
    } catch (e) {
      print(e);
    }
  }

  Future<void> savePojo(List<dynamic> crosspromoobject) async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    pref.setString('userData', json.encode(crosspromoobject));
    print(crosspromoobject);
  }

  void tapped(int index) {
    Fluttertoast.showToast(
        msg: crosspromoobject[index].app_name,
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIosWeb: 1,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 16.0);
  }
}

【问题讨论】:

  • 在返回容器之前检查这个snapshot.connectionState == ConnectionState.done
  • 在你告诉“if(snapshot.connectionState == ConnectionState.done) return Container(”之后,仍然存在同样的问题。我确实在这个调用“future:getCrosspromodata()”之后调试了它。但是在 getCrosspromodata() 我得到所需的值。

标签: flutter dart gridview scroll


【解决方案1】:

尝试将GridView的属性shrinkWrap设置为true

GridView.builder(
   shrinkWrap: true,
   //...
)

【讨论】:

    【解决方案2】:

    所以我通过在 CustomScrollView 中获取 SliverList 和 SliverChildListDelegate 并在 FutureBuilder 中为容器提供高度高度:SizeConfig.screenHeight / 1.10,下面是完整的代码。

    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      // Initialize without device test ids
      Admob.initialize();
      // Add a list of test ids.
      // Admob.initialize(testDeviceIds: ['YOUR DEVICE ID']);
    
      runApp(FirstScreen());
    }
    
    class FirstScreen extends StatefulWidget {
      @override
      _CrosspromoPageState createState() => _CrosspromoPageState();
    }
    
    class _CrosspromoPageState extends State<FirstScreen> {
      AdmobInterstitial interstitialAd;
      List<CrosspromotionPojo> crosspromoobject = List();
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        // getCrosspromodata();
        // loadcrossPromodata();
     
      }
    
      @override
      Widget build(BuildContext context) {
        SizeConfig().init(context);
        SizeConfig().init(context);
        return Scaffold(
            body: Container(
                child: CustomScrollView(slivers: <Widget>[
          SliverList(
              delegate: SliverChildListDelegate(
            [
              Stack(
                children: [
                  new Image.asset('assets/images/bg_half_image.jpg'),
                  new Align(
                      alignment: Alignment.topCenter,
                      child: new Container(
                        margin: EdgeInsets.fromLTRB(0, 55, 0, 0),
                        width: 150,
                        height: 150,
                        child: Image.asset('assets/images/logo.png'),
                      )),
                  new Align(
                      alignment: Alignment.topCenter,
                      child: InkWell(
                          onTap: () async {
                            if (await interstitialAd.isLoaded) {
                              interstitialAd.show();
                            }
                            int val = await DatabaseHelper.instance.queryRowCount();
                            if (val == 0) {
                              DatabaseHelper.instance.insertExcdaydata();
                              DatabaseHelper.instance.insertExcdaydatainapp();
                            } else
                              Navigator.pop(context, true);
                            {
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) => BannerPage(),
                                ),
                              );
                            }
                          },
                          child: new Container(
                            width: 150,
                            margin: EdgeInsets.fromLTRB(0, 200, 0, 0),
                            //padding: EdgeInsets.fromLTRB(4, 0, 4, 4),
                            child: new Image.asset('assets/images/start.png'),
                          )))
                ],
              ),
              new SizedBox(
                height: 50,
                width: double.infinity,
                child: Container(
                  margin: EdgeInsets.fromLTRB(0, 15, 0, 0),
                  color: Colors.white,
                  child: Text(
                    "TRY OUR NEW APPS",
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        color: Colors.black,
                        fontWeight: FontWeight.bold,
                        fontSize: 20),
                  ),
                ),
              ),
              new FutureBuilder<dynamic>(
                  future: getCrosspromodata(),
                  builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                    if (snapshot.connectionState == ConnectionState.waiting) {
                      return Center(child: Text('Please wait its loading...'));
                    } else {
                      return Container(
                        height: SizeConfig.screenHeight / 1.10,
                        margin:
                            EdgeInsets.only(left: 0, right: 0, top: 0, bottom: 0),
                        child: Align(
                          child: GridView.builder(
                            itemCount: crosspromoobject.length,
                            itemBuilder: (context, index) => GestureDetector(
                              onTap: () => tapped(index),
                              child: Container(
                                  child: new Card(
                                elevation: 2,
                                child: Column(
                                  children: <Widget>[
                                    new Container(
                                      child: CachedNetworkImage(
                                        imageUrl: crosspromoobject[index].appUrl,
                                        placeholder: (context, url) =>
                                            CircularProgressIndicator(),
                                        errorWidget: (context, url, error) =>
                                            Icon(Icons.error),
                                      ),
                                    ),
                                    new Container(
                                        alignment: AlignmentDirectional.centerStart,
                                        child: Text(
                                          crosspromoobject[index].app_name,
                                          style: TextStyle(
                                              color: Colors.black, fontSize: 15),
                                        ))
                                  ],
                                ),
                              )),
                            ),
                            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                              crossAxisCount: 3,
                              mainAxisSpacing: 30,
                              crossAxisSpacing: 15,
                              childAspectRatio: MediaQuery.of(context).size.width /
                                  (MediaQuery.of(context).size.height / 1.1),
                            ),
                          ),
                        ),
                      );
                    }
                  })
            ],
          )),
        ]))
            // This trailing comma makes auto-formatting nicer for build methods.
            );
      }
    
      Future<String> loadcrossPromodata() async {
        SharedPreferences pref = await SharedPreferences.getInstance();
        List<dynamic> tagObjsJson =
            (json.decode(pref.getString('userData')) ?? List<dynamic>());
        crosspromoobject = tagObjsJson
            .map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
            .toList();
      }
    
      Future<dynamic> getCrosspromodata() async {
        List<dynamic> tagObjsJson;
        SharedPreferences pref = await SharedPreferences.getInstance();
        try {
          Response<Map> versionresponse = await Dio().get(
              "https://videomergerapp.com/mobilestores/https/cross_promo_photoapps/verison.json");
          Map arrayObjresponse = versionresponse.data;
          int version = arrayObjresponse['healthw_version'];
          int localversion = pref.getInt('local_version') ?? 0;
          if (version > localversion) {
            Response<Map> response = await Dio().get(
                "https://videomergerapp.com/mobilestores/https/cross_promo_fitness/cross_promo_health_fitness_firstscreen.json");
            String arrayObjsText = response.toString();
            tagObjsJson = jsonDecode(arrayObjsText)['item_array'] as List;
            crosspromoobject = tagObjsJson
                .map((tagJson) => CrosspromotionPojo.fromJson(tagJson))
                .toList();
            savePojo(tagObjsJson);
            pref.setInt('local_version', version);
            return tagObjsJson;
          } else {
            loadcrossPromodata();
          }
        } catch (e) {
          print(e);
        }
      }
    
      Future<void> savePojo(List<dynamic> crosspromoobject) async {
        SharedPreferences pref = await SharedPreferences.getInstance();
        pref.setString('userData', json.encode(crosspromoobject));
        print(crosspromoobject);
      }
    
      void tapped(int index) {
        Fluttertoast.showToast(
            msg: crosspromoobject[index].app_name,
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
            timeInSecForIosWeb: 1,
            backgroundColor: Colors.red,
            textColor: Colors.white,
            fontSize: 16.0);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-18
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 2019-10-07
      • 1970-01-01
      相关资源
      最近更新 更多