【问题标题】:Flutter Failed assertion: boolean expression must not be nullFlutter 断言失败:布尔表达式不能为空
【发布时间】:2021-06-06 06:29:42
【问题描述】:

我在 Vipin Vijayan 的 tutorial on parsing JSON in ListView 上关注 Flutter 的 fetch data from the internet cookbook 并收到以下错误:

═══════════════════════════════════小部件库捕获的异常 ═══════════════════════════════════抛出以下断言 构建 MyApp(脏,状态:_MyAppState#a2d98):断言失败: 布尔表达式不能为空

相关的导致错误的小部件是 MyApp package:le_moineau/main.dart:35 抛出异常时,这个 是堆栈 #0 _MyAppState.build 包:le_moineau/main.dart:70 #1 StatefulElement.build 包:flutter/…/widgets/framework.dart:4802 #2 ComponentElement.performRebuild package:flutter/…/widgets/framework.dart:4685 #3 StatefulElement.performRebuild 包:flutter/…/widgets/framework.dart:4857 #4 Element.rebuild package:flutter/.../widgets/framework.dart:4379 ...

这是我的 Users.dart 使用 https://app.quicktype.io/ 解析的代码

// To parse this JSON data, do
//
//     final users = usersFromJson(jsonString);

import 'dart:convert';

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

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

class User {
  User({
    this.userId,
    this.id,
    this.title,
    this.completed,
  });

  int userId;
  int id;
  String title;
  bool completed;

  factory User.fromJson(Map<String, dynamic> json) => User(
        userId: json["userId"],
        id: json["id"],
        title: json["title"],
        completed: json["completed"],
      );

  Map<String, dynamic> toJson() => {
        "userId": userId,
        "id": id,
        "title": title,
        "completed": completed,
      };
}

这是我的 main.dart 代码:

import 'dart:async';
//import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'others/Users.dart';

class MyHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext context) {
    return super.createHttpClient(context)
      ..badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
  }
}

Future<List<User>> getUsers() async {
  final response =
      await http.get(Uri.https('jsonplaceholder.typicode.com', 'todos'));

  //await http.get("https://192.168.1.4:8081/json/todos.json");
  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    final List<User> users = usersFromJson(response.body);
    return users;
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load users');
  }
}

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

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  List<User> _users;
  bool _loading;

  @override
  void initState() {
    HttpOverrides.global = new MyHttpOverrides();
    super.initState();
    _loading = true;
    getUsers().then((users) {
      setState(() {
        _users = users;
        _loading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text(_loading ? 'Loading...' : 'Users'),
        ),
        body: Container(
          color: Colors.white,
          child: ListView.builder(
              itemCount: null == _users ? 0 : _users.length,
              itemBuilder: (context, index) {
                User user = _users[index];
                return ListTile(
                  title: Text('This is a test'),
                  subtitle: Text(user.title),
                );
              }),
        ),
      ),
    );
  }
}

即使我使用 Vipin 的股票 Widget Build 代码,我也会遇到同样的错误。有人可以看看并给我一些建议吗?

【问题讨论】:

    标签: json flutter listview


    【解决方案1】:

    尝试在bool变量中初始化真值

    bool _loading = true; 
    

    并删除initState()中的_loading = true;

    【讨论】:

      【解决方案2】:

      由于 Flutter 2.0.x 附带 Null Safety,因此不允许使用 bool _loading;,因此您可以使用 bool? _loading;bool _loading = true;? 表示您的变量接受空值。

      更新:插入代码

      网络服务

      class NetService {
      ...
        static Future<T?> getJson<T>(String url, {int okCode = 200}) {
          return http.get(Uri.parse(url))
            .then((response) {
              if (response.statusCode == okCode) {
                return jsonDecode(response.body) as T;
              }
              _printDataNotOK(response);
              return null;
            })
            .catchError((err) => _printError(err));
        }
      ....
      }
      

      json_placeholder_service.dart

      import 'dart:async';
      
      import 'package:jsonplaceholder/services/networking.dart';
      
      
      class JsonPlaceholderService {
        static const _baseUrl = 'https://jsonplaceholder.typicode.com';
        /* ---------------------------------------------------------------------------- */
        static Future<List?> _doGet(String path) async {
          return await NetService.getJson<List>(_baseUrl + path)
            .whenComplete(() => print('\nFetching done!'));
        }
        /* ---------------------------------------------------------------------------- */
        static Future<List?> fetchTodos() => _doGet('/todos');
      }
      

      home_page.dart

      import 'package:flutter/material.dart';
      import 'package:jsonplaceholder/services/json_placeholder_service.dart';
      
      
      class HomePage extends StatelessWidget {
        /* ---------------------------------------------------------------------------- */
        const HomePage({Key? key}) : super(key: key);
        /* ---------------------------------------------------------------------------- */
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Text('Hi!'),
              centerTitle: true,
            ),
            body: SingleChildScrollView(
              child: FutureBuilder<List?>(
                future: JsonPlaceholderService.fetchTodos(),
                builder: (context, snapshot) {
                  if (snapshot.hasError) return Text(snapshot.error.toString());
                  if (snapshot.connectionState == ConnectionState.done) {
                    var data = snapshot.data;
                    if (data != null && data.isNotEmpty) {
                      return Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: List<Widget>.generate(data.length, (i) {
                          var item = data[i];
                          return Text('${item['userId']} - ${item['id']} - ${item['title']}');
                        }),
                      );
                    }
                    return Text('No data received!');
                  }
                  return CircularProgressIndicator();
                },
              ),
            ),
          );
        }
      }
      

      结果:

      【讨论】:

      • 感谢您的解释,这确实消除了错误,但我的应用程序仍然没有显示任何 JSON 数据。有什么想法吗?
      • 这是使用快照,它不是我要找的。不过,谢谢。
      猜你喜欢
      • 2020-11-02
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 2020-07-05
      • 2020-04-23
      相关资源
      最近更新 更多