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

Flutter项目报错:TypeError 'Null'不是'(Quote)=>dynamic'的子类型

Flutter 删除语录按钮 TypeError 问题解决

问题场景

开发展示文本并通过按钮删除文本的Flutter应用,运行时抛出错误:

Exception has occured
_TypeError (type 'Null' is not a subtype of type '(Quote) => dynamic')

涉及三个Dart文件:main.dart、QuoteCard.dart、quote.dart。

错误原因

  1. main.dart中回调传递方式错误:
    在quotes.map创建QuoteCard时,onRemoveData: delete(quote)是直接执行delete函数,而非传递函数引用。delete执行后返回void(即Null),但onRemoveData需要接收Function(Quote)类型的回调,类型不匹配导致报错。

  2. QuoteCard.dart中按钮点击事件绑定错误:
    TextButton的onPressed属性需要无参函数(VoidCallback),但onRemoveData(quote)是直接执行回调函数,返回Null,不符合类型要求。

修正方案

1. 修改main.dart

将QuoteCard的onRemoveData参数改为传递函数引用:

// 原错误代码
children: quotes.map((quote) => QuoteCard(
  quote: quote,
  onRemoveData: delete(quote),
)).toList(),

// 修改后代码
children: quotes.map((quote) => QuoteCard(
  quote: quote,
  onRemoveData: delete,
)).toList(),

2. 修改QuoteCard.dart

将TextButton的onPressed改为匿名函数,确保点击时才执行回调:

// 原错误代码
TextButton.icon(
  onPressed: onRemoveData(quote),
  label: Text('delete quote'),
  icon: Icon(Icons.delete),
)

// 修改后代码
TextButton.icon(
  onPressed: () => onRemoveData(quote),
  label: Text('delete quote'),
  icon: Icon(Icons.delete),
)

修正后的完整代码

main.dart

// ignore_for_file: prefer_const_literals_to_create_immutables, prefer_const_constructors_in_immutables, use_key_in_widget_constructors

import 'package:flutter/material.dart';
import 'quote.dart';
import 'QuoteCard.dart';

void main() => runApp(MaterialApp(
  home: QuoteList()
));

class QuoteList extends StatefulWidget {
  const QuoteList({super.key});

  @override
  State<QuoteList> createState() => QuoteListState();
}

class QuoteListState extends State<QuoteList> {

  List<Quote> quotes = [
  Quote(text: 'hello', author: 'Pete'),
  Quote(text: 'hi', author: 'Bill'),
  Quote(text: 'hey', author: 'Tom')
  ];

  void delete(Quote quote) {
    setState(() {
      quotes.remove(quote);
    });
  } 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text('quotes'),
        centerTitle: true,
        backgroundColor: Colors.redAccent,
      ),
      body: Column(
        children: quotes.map((quote) => QuoteCard(
          quote: quote,
          onRemoveData: delete,
        )).toList(),
    ) );
  }
}

QuoteCard.dart

import 'package:flutter/material.dart';
import 'quote.dart';

class QuoteCard extends StatelessWidget {
  
  final Quote quote;
  final Function(Quote) onRemoveData;
  QuoteCard({required this.quote, required this.onRemoveData});
  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 0.0),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Text(
              quote.text,
              style: TextStyle(
                fontSize: 18.0,
                color: Colors.grey[800]
              ),
            ),
            SizedBox(height: 6.0,),
            Text(
              quote.author,
              style: TextStyle(
                fontSize: 10.0,
                color: Colors.grey[700]
              ),
            ),
            SizedBox(height: 8.0,),
            TextButton.icon(
              onPressed: () => onRemoveData(quote),
              label: Text('delete quote'),
              icon: Icon(Icons.delete),
            )
          ],
        ),
      ),
    );
  }
}

quote.dart(无需修改)

class Quote {
  String text;
  String author;
  Quote({required this.text, required this.author});
}

补充说明

  • 传递回调时要区分函数引用和函数执行:直接写函数名是传递引用(如delete),加括号传参是立即执行函数(如delete(quote)),后者会返回执行结果而非传递函数本身。
  • 按钮onPressed必须是无参函数,因此需要用匿名函数() => ...包装带参回调,确保仅在点击时执行。

内容的提问来源于stack exchange,提问作者Siddharth Chopra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:16:03