You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter词典应用搜索栏LateInitializationError问题修复请求

问题分析与解决

错误原因

  1. 未初始化的_debounce变量:代码用late Timer _debounce;声明了延迟初始化变量,但initState里未给它赋值。第一次在搜索栏输入文本触发onChanged时,访问_debounce.isActive会直接抛出LateInitializationError——变量还未被初始化。
  2. API字段拼写错误:Owlbot词典API返回的定义数组字段是definitions(正确复数拼写),但代码里错误写成了defination/definations,会导致搜索成功后渲染数据时出现异常。

修复步骤

1. 修复定时器初始化问题

将late Timer _debounce;改为可空类型,避免强制延迟初始化的限制:

Timer? _debounce;

同时修改onChanged中的判断逻辑,确保安全访问定时器状态:

onChanged: (String text) {
  // 先判断定时器是否存在且活跃,再取消
  if (_debounce?.isActive ?? false) _debounce!.cancel();
  _debounce = Timer(const Duration(milliseconds: 1000), () {
    searchText();
  });
},

2. 修正API字段拼写错误

  • 将列表长度判断中的snapshot.data["defination"].length改为:
    itemCount: snapshot.data["definitions"].length,
    
  • 将ListTile中的snapshot.data["definations"][index]改为:
    snapshot.data["definitions"][index]
    
  • 将定义文本中的snapshot.data["defination"][index]["defination"]改为:
    snapshot.data["definitions"][index]["definition"]
    

3. 优化:添加资源清理(可选)

在dispose方法中关闭流控制器、销毁文本控制器并取消定时器,避免内存泄漏:

@override
void dispose() {
  _streamController.close();
  textEditingController.dispose();
  _debounce?.cancel(); // 清理定时器
  super.dispose();
}

完整修正代码

import 'dart:async';
import 'dart:convert';

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String url = "https://owlbot.info/api/v4/dictionary/";
  String token = "7ba05536bd11ff8e22800cbda80951376c59ed84";
  TextEditingController textEditingController = TextEditingController();
  late StreamController _streamController;
  late Stream _stream;
  Timer? _debounce; // 修改为可空类型

  searchText() async {
    if (textEditingController.text.isEmpty) {
      _streamController.add(null);
      return;
    }
    _streamController.add("waiting");
    Uri uri = Uri.parse(url + textEditingController.text.trim());
    http.Response response = await http.get(uri, headers: {"Authorization": "Token " + token});
    _streamController.add(json.decode(response.body));
  }

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

  @override
  void dispose() {
    _streamController.close();
    textEditingController.dispose();
    _debounce?.cancel(); // 清理定时器
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.green,
        title: Text(
          "Dictionary", // 修正拼写错误
          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),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(24),
                  ),
                  child: TextFormField(
                    onChanged: (String text) {
                      if (_debounce?.isActive ?? false) _debounce!.cancel();
                      _debounce = Timer(const Duration(milliseconds: 1000), () {
                        searchText();
                      });
                    },
                    controller: textEditingController,
                    decoration: InputDecoration(
                      hintText: "Search for Word",
                      contentPadding: const EdgeInsets.only(left: 24),
                      border: InputBorder.none,
                    ),
                  ),
                ),
              ),
              IconButton(
                icon: Icon(
                  Icons.search,
                  color: Colors.white,
                ),
                onPressed: () {
                  searchText();
                },
              ),
            ],
          ),
        ),
      ),
      body: Container(
        margin: EdgeInsets.all(8.0),
        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(),
              );
            }

            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,
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Muhammad Danish Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:10:13