【问题标题】:Getting This Error on Run Time "Null check operator used on a null value"在运行时出现此错误“用于空值的空检查运算符”
【发布时间】:2021-10-10 16:46:47
【问题描述】:

我正在使用 api owlbot 构建一个字典应用程序。我的代码运行罚款没有显示错误。但是在运行时间之后,我收到错误════════小部件捕获的异常══════════════════════════════════ ══════════════ 用于空值的空检查运算符 ══════════════════════════════════════════════════ ══════════════════

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DictionaryPage(),
    );
  }
}

我的词典页面代码:

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

class DictionaryPage extends StatefulWidget {
  @override
  _DictionaryPageState createState() => _DictionaryPageState();
}

class _DictionaryPageState extends State<DictionaryPage> {
  String url = "https://owlbot.info/api/v4/dictionary/";
  String token = "Your Key";

  TextEditingController textEditingController = TextEditingController();

  // Stream for loading the text as soon as it is typed
  late StreamController streamController;
  Stream? _stream;

  Timer? _debounce;

  // search function
  searchText() async {
    if (textEditingController.text.length == 0) {
      streamController.add(null);
      return;
    }
    streamController.add("waiting");
    Response response =
        await get(url + textEditingController.text.trim() as Uri,
            // do provide spacing after Token
            headers: {"Authorization": "Token " + token});
    streamController.add(json.decode(response.body));
  }

  @override
  void initState() {
    super.initState();
    streamController = StreamController();
    _stream = streamController.stream;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.black,
          title: Text(
            "Dictionary nw",
            style: TextStyle(color: Colors.white),
          ),
          centerTitle: true,
          bottom: PreferredSize(
            preferredSize: Size.fromHeight(45),
            child: Row(
              children: [
                Expanded(
                  child: Container(
                    margin: const EdgeInsets.only(left: 12, bottom: 11.0),
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(24.0),
                        color: Colors.white),
                    child: TextFormField(
                      onChanged: (String? text) {
                        if (_debounce!.isActive) _debounce?.cancel();
                        _debounce =
                            Timer(const Duration(milliseconds: 1000), () {
                          searchText();
                        });
                      },
                      controller: textEditingController,
                      decoration: InputDecoration(
                        hintText: "Search for a word",
                        contentPadding: const EdgeInsets.only(left: 24.0),

                        // removing the input border
                        border: InputBorder.none,
                      ),
                    ),
                  ),
                ),
                IconButton(
                  icon: Icon(
                    Icons.search,
                    color: Colors.white,
                  ),
                  onPressed: () {
                    searchText();
                  },
                )
              ],
            ),
          ),
        ),
        body: Container(
          margin: EdgeInsets.all(8),
          child: StreamBuilder(
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.data == null) {
                return Center(
                  child: Text("Enter a search word"),
                );
              }
              if (snapshot.data == "waiting") {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }

              // output
              return ListView.builder(
                itemCount: snapshot.data["definitions"].length,
                itemBuilder: (BuildContext context, int index) {
                  return ListBody(
                    children: [
                      Container(
                        color: Colors.grey[300],
                        child: ListTile(
                          leading: snapshot.data["definitions"][index]
                                      ["image_url"] ==
                                  null
                              ? null
                              : CircleAvatar(
                                  backgroundImage: NetworkImage(snapshot
                                      .data["definitions"][index]["image_url"]),
                                ),
                          title: Text(textEditingController.text.trim() +
                              "(" +
                              snapshot.data["definitions"][index]["type"] +
                              ")"),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                            snapshot.data["definitions"][index]["definition"]),
                      )
                    ],
                  );
                },
              );
            },
            stream: _stream,
          ),
        ),
      ),
    );
  }
}

根据我的研究,我认为这个错误发生在 ,

   if (_debounce!.isActive) _debounce?.cancel();
                        _debounce =
                            Timer(const Duration(milliseconds: 1000), () {
                          searchText();
                        });
                      },
                     

这个,我需要根据这个改变,

Use a local variable

var f = foo;
if (f != null) {
  var len = f.length; // Safe 
}
Use ?. and ??

var len = foo?.length ?? 0; 

【问题讨论】:

    标签: flutter flutter-layout flutter-dependencies flutter-test dart-null-safety


    【解决方案1】:

    您需要检查_debounce 是否已经初始化(即它不为空):

    onChanged: (String? text) {
      // Use a local variable, as your snippet hints
      final Timer? debounce = _debounce;
    
      // Check if it's initialized AND if it's active
      if (debounce != null && debounce.isActive)
        debounce.cancel();
    
      // Initialize a new timer
      _debounce = Timer(const Duration(milliseconds: 1000), () {
        searchText();
      });
    },
    

    【讨论】:

    • 就这么做:debounce?.cancel();。如果您在非活动计时器上调用 cancel(),则不会发生任何事情,因此无需测试它是否处于活动状态:api.dart.dev/stable/2.13.4/dart-async/Timer/cancel.html
    • 在“?.”的情况下运算符,您也可以省略对局部变量的赋值。
    猜你喜欢
    • 1970-01-01
    • 2021-09-01
    • 2021-11-04
    • 2022-06-19
    • 2021-12-25
    • 2021-09-10
    • 2022-08-06
    • 1970-01-01
    • 2021-01-24
    相关资源
    最近更新 更多