【问题标题】:Checking isEmpty data in flutter GridView.builder在flutter GridView.builder中检查isEmpty数据
【发布时间】:2020-08-20 05:28:36
【问题描述】:

当没有数据时,我想在flutter gridview中显示一个文本小部件(“未找到数据”)。我也使用了嵌套三元运算符,但不起作用。

这是我正在尝试的代码。 创建了一个 gridview 小部件。

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:recipe_app/models/recipe.dart';
import 'package:recipe_app/services/recipe_service.dart';
import 'package:recipe_app/widgets/recipe_by_category.dart';

class RecipesByCategoryName extends StatefulWidget {
  final String categoryName;
  final String categoryIcon;
  final int categoryId;
  RecipesByCategoryName(
      {this.categoryIcon, this.categoryId, this.categoryName});
  @override
  _RecipesByCategoryNameState createState() => _RecipesByCategoryNameState();
}

class _RecipesByCategoryNameState extends State<RecipesByCategoryName> {
  RecipeService _recipesService = RecipeService();
  List<Recipe> _recipeListByCategory = List<Recipe>();
  bool isLoading = true;

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

  _getRecipesByCategory() async {
    var products =
        await _recipesService.getRecipesByCategoryId(widget.categoryId);
    var _list = json.decode(products.body);
    _list["data"].forEach((data) {
      var model = Recipe();
      model.id = data["id"];
      model.title = data["recipeTitle"];
      model.image = data["recipePhoto"];
      model.cookTime = data["cookTime"].toString();
      model.ingredients = data["recipeIngredient"];
      model.directions = data["recipeDirection"];

      setState(() {
          _recipeListByCategory.add(model);
          isLoading = false;
      });
    });
  }

  Widget getGridView(){
    return (_recipeListByCategory?.length != 0) ? GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: _recipeListByCategory.length,
      itemBuilder: (context, index) {
        return RecipeByCategory(
          this._recipeListByCategory[index],

        );
      },
    ) : Text("No Data Found");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text(this.widget.categoryName)),
        body: Container(
          child: Center(
            child: isLoading
                ? CircularProgressIndicator(
              backgroundColor: Colors.deepPurpleAccent,
              strokeWidth: 10,
            )
                :
            getGridView()
          ),
        ));
  }
}

更新 当没有数据时,我想在颤动的网格视图中显示一个文本小部件(“未找到数据”)。我也使用了嵌套三元运算符,但不起作用。

请查看 isLoading 函数。

【问题讨论】:

  • 究竟是什么不起作用?显示正在发生的事情或您有什么错误,也无需将您的文本小部件包装在中心,因为 getGridView 已经在其中
  • 可以上传完整代码吗?
  • @EdwynZN 我没有收到任何错误。仅显示 CirculaprogressIndicator。我无法显示空短信
  • isLoading 永远不会是假的,在你的情况下,检查它的值,当它变为真时也看看
  • 可以上传完整代码吗?

标签: flutter flutter-layout


【解决方案1】:

试试这样的。它可能会解决您的问题。

Widget getGridView(){
   if(_recipeListByCategory.length > 0) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: _recipeListByCategory.length,
      itemBuilder: (context, index) {
        return RecipeByCategory(
          this._recipeListByCategory[index],
        );
      },
    );
   } else{
      return Center(child: Text("No Data Found"),);
  }
}

这是因为,isLoading 永远不会变为 false,并且在您的 async 函数中,setStateforEach 之外

_getRecipesByCategory() async {
    var products =
        await _recipesService.getRecipesByCategoryId(widget.categoryId);
    var _list = json.decode(products.body);
    List<Recipe> results = [];
    _list["data"].forEach((data) {
      var model = Recipe();
      model.id = data["id"];
      model.title = data["recipeTitle"];
      model.image = data["recipePhoto"];
      model.cookTime = data["cookTime"].toString();
      model.ingredients = data["recipeIngredient"];
      model.directions = data["recipeDirection"];
      results.add(model);
    });
    setState(() {
          _recipeListByCategory = results;
          isLoading = false;
    });
 }

【讨论】:

  • 不客气。确保您正在实施我现在编辑的答案。为每个元素调用 setState 并不是最佳实践。所以,最后setState 整个列表。
  • 请问您能帮帮我吗?我想在这个答案中添加连接检查功能,但我只得到循环进度请stackoverflow.com/questions/63665111/…
  • 当然!但请在新问题中发布您的最新代码和预期结果。
【解决方案2】:
Widget getGridView(){
    return _recipeListByCategory != [] ? GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: _recipeListByCategory.length,
      itemBuilder: (context, index) {
        return RecipeByCategory(
          this._recipeListByCategory[index],
        );
      },
    ) : Center(child: Text("No Data Found"),);
  }

Widget getGridView(){
    return (_recipeListByCategory?.length != 0) ? GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: _recipeListByCategory.length,
      itemBuilder: (context, index) {
        return RecipeByCategory(
          this._recipeListByCategory[index],
        );
      },
    ) : Center(child: Text("No Data Found"),);
  }

【讨论】:

  • 感谢@spycbanda 检查两种解决方案后遇到同样的问题。
  • 这是因为您的 _recipeListByCategory 未重新分配,或者您的 Widget 未刷新,或者两者兼而有之。你用过 setState((){ _recipeListByCategory = fetchedRecipes});其中 fetchedRecipes 是点击 API 获取请求后获取的食谱
  • 请查看完整代码。我认为 isLoading 函数没有正确使用。
猜你喜欢
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-06
相关资源
最近更新 更多