data!= null :必须向 Text 小部件提供非 null 字符串

Posted

技术标签:

【中文标题】data!= null :必须向 Text 小部件提供非 null 字符串【英文标题】:data!= null : A non-null String must be provided to a Text widget 【发布时间】:2020-11-18 17:18:57 【问题描述】:

我是 Flutter 的新手,我收到了这个错误:A non-null String must be provided to a Text widget。我试图修复它,但它不会。 api响应很好,这里是url:https://appiconmakers.com/demoMusicPlayer/API/getallcategories

这是我写的代码,

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

class CategoryTab extends StatefulWidget 
     @override
     _CategoryTabState createState() => _CategoryTabState();


class _CategoryTabState extends State<CategoryTab> 
    @override
    void initState() 
        // TODO: implement initState
        super.initState();
    

    Future<List<CategoryList>> _getUsers() async 

        var data = await http.get("https://appiconmakers.com/demoMusicPlayer/API/getallcategories");

        var jsonData = json.decode(data.body);

        List<CategoryList> cat = [];

        for (var u in jsonData) 

            CategoryList categoryList = CategoryList(u["categoryId"], u["categoryName"], u["parentCategoryId"], u["categoryStatus"], u["createdDate"]);

            cat.add(categoryList);

        
        print("=================================");

        print(cat.length);

        return cat;

    

    @override
    Widget build(BuildContext context) 
        return Scaffold(
            appBar: AppBar(
                title: Text("Categories", style: TextStyle(color:Colors.black)),
                backgroundColor: Colors.white,
        ), body: 
        Container(
            child: FutureBuilder(
                future: _getUsers(),
                builder: (BuildContext context, AsyncSnapshot snapshot) 
                    print(snapshot.data);
                    if (snapshot.data == null) 
                        return Container(
                            child: Center(child: Text("Loading..."))
                        );
                     else 
                        return ListView.builder(
                            itemCount: snapshot.data.length,
                            itemBuilder: (BuildContext context, int index) 
                                return ListTile(
                                    leading: CircleAvatar(),
                                    title: Text(snapshot.data[index].categoryName,
                                    // subtitle: Text(snapshot.data[index].categoryId),
                                );
                            ,
                        );
                    
                ),
            ),
        );
    


class CategoryList 
    String categoryId;
    String categoryName;
    String parentCategoryId;
    String categoryStatus;
    String createdDate;

    CategoryList(this.categoryId, this.categoryName, this.parentCategoryId, this.categoryStatus, this.createdDate);

调试部分也给了我这个结果:

 [        ] flutter: =================================
 [        ] [DEVICE LOG] 2020-07-29 08:05:00.688910+0300  localhost Runner[20673]: (Flutter)      flutter: 9
 [        ] flutter: 9
 [        ] [DEVICE LOG] 2020-07-29 08:05:00.690942+0300  localhost Runner[20673]: (Flutter)  flutter:
[Instance of 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList', Instance of
'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList', Instance of  'CategoryList',
Instance of 'CategoryList', Instance of 'CategoryList']
[        ] flutter: [Instance of 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList',
Instance of 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList', Instance of
 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList']
 [   +1 ms] [DEVICE LOG] 2020-07-29 08:05:00.692566+0300  localhost Runner[20673]: (Flutter)   flutter:
 Another exception was thrown: A non-null String must be provided to a Text widget.
 [        ] flutter: Another exception was thrown: A non-null String must be provided to a  Text widget.

【问题讨论】:

【参考方案1】:

只需进行以下更新:

title: Text(snapshot.data[index].categoryName ?? '',
              // subtitle: Text(snapshot.data[index].categoryId
              ),

现在如果 snapsho.data[index].categoryName 为 null,则空字符串将分配给文本小部件。

如果您想查看数据是否存在,则只需打印 snapshot.data 即可查看数据是否存在。

【讨论】:

【参考方案2】:

替换title: Text(snapshot.data[index].categoryName,title: Text(snapshot.data[index].categoryName ?? “Some Text To Display if Null”

应该这样做。 ?? 后面的值如果为 null 则替换前面的值

查看this answer 了解有关?? 运算符的更多信息

【讨论】:

【参考方案3】:

替换此代码

CategoryList categoryList = CategoryList(u["categoryId"], u["categoryName"], u["parentCategoryId"], u["categoryStatus"], u["createdDate"]);

CategoryList categoryList = CategoryList(u["category_id"], u["category_name"], u["parent_category_id"], u["category_status"], u["created_date"]);

【讨论】:

其实这是最好的解决方案,谢谢@shubham chhimpa【参考方案4】:

只需检查答案

json 的模型类:

// To parse this JSON data, do
//
//     final categoryList = categoryListFromJson(jsonString);

import 'dart:convert';

List<CategoryList> categoryListFromJson(String str) => List<CategoryList>.from(json.decode(str).map((x) => CategoryList.fromJson(x)));

String categoryListToJson(List<CategoryList> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class CategoryList 
    CategoryList(
        this.categoryId,
        this.categoryName,
        this.parentCategoryId,
        this.categoryStatus,
        this.createdDate,
        this.subcategory,
    );

    String categoryId;
    String categoryName;
    String parentCategoryId;
    String categoryStatus;
    DateTime createdDate;
    List<CategoryList> subcategory;

    factory CategoryList.fromJson(Map<String, dynamic> json) => CategoryList(
        categoryId: json["category_id"],
        categoryName: json["category_name"],
        parentCategoryId: json["parent_category_id"],
        categoryStatus: json["category_status"],
        createdDate: DateTime.parse(json["created_date"]),
        subcategory: List<CategoryList>.from(json["subcategory"].map((x) => CategoryList.fromJson(x))),
    );

    Map<String, dynamic> toJson() => 
        "category_id": categoryId,
        "category_name": categoryName,
        "parent_category_id": parentCategoryId,
        "category_status": categoryStatus,
        "created_date": createdDate.toIso8601String(),
        "subcategory": List<dynamic>.from(subcategory.map((x) => x.toJson())),
    ;




用户界面:

import 'dart:convert';

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(home: HomePage());
  


class HomePage extends StatefulWidget 
  @override
  _HomePageState createState() => _HomePageState();


class _HomePageState extends State<HomePage> 
  double value;
  @override
  void initState() 
    super.initState();
  

  Future<List<CategoryList>> _getUsers() async 
    var data = await http
        .get("https://appiconmakers.com/demoMusicPlayer/API/getallcategories");

    final categoryList = categoryListFromJson(data.body);
    List<CategoryList> cat = [];

    categoryList.forEach((element) 
      cat.add(CategoryList(
          categoryId: element.categoryId,
          categoryName: element.categoryName,
          parentCategoryId: element.parentCategoryId,
          categoryStatus: element.categoryStatus,
          createdDate: element.createdDate.toString()));
    );

    print("=================================");

    print(cat.length);

    return cat;
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Categories",
          style: TextStyle(color: Colors.black),
        ),
        backgroundColor: Colors.white,
      ),
      body: Container(
        child: FutureBuilder(
          future: _getUsers(),
          builder: (BuildContext context, AsyncSnapshot snapshot) 
            print(snapshot.data);

            if (snapshot.data == null) 
              return Container(child: Center(child: Text("Loading...")));
             else 
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) 
                  return ListTile(
                    leading: CircleAvatar(),
                    title: Text(
                      snapshot.data[index].categoryName,
                      // subtitle: Text(snapshot.data[index].categoryId
                    ),
                  );
                ,
              );
            
          ,
        ),
      ),
    );
  


class CategoryList 
  String categoryId;
  String categoryName;
  String parentCategoryId;
  String categoryStatus;
  String createdDate;

  CategoryList(
      this.categoryId,
      this.categoryName,
      this.parentCategoryId,
      this.categoryStatus,
      this.createdDate);


让我知道它是否有效。

【讨论】:

以上是关于data!= null :必须向 Text 小部件提供非 null 字符串的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 必须向 Text 小部件提供非空字符串

必须向 Text 小部件 Flutter Api 提供非空字符串

必须向 Text 小部件提供非空字符串

必须向 Text 小部件提供非空字符串 - 颤振

从 API 返回的 Text 小部件内的 Null 值

Flutter null 安全条件小部件