如何为Flutter按钮添加Navigator.push 解决Null Function()无法赋值给Widget错误
报错根因
你遇到的The element type 'Null Function()' can't be assigned to the list type 'Widget'错误,是因为你直接把可执行函数放到了Row的children数组里,这个数组要求所有元素都是Widget类型,函数不属于Widget,所以触发类型不匹配报错。
除此之外你的代码还有几个明显问题:
TypeFilter类的构造函数名写错了,写成了CategoriesTypeFilter,和类名不匹配- 声明的
funct变量没有初始化,运行时调用会触发空指针异常 - 导航跳转逻辑不该单独放在children数组里,应该写到按钮的点击事件回调中
修复后的完整代码
import 'package:flutter/material.dart'; // 这里假设你已经定义了MetamorphicAnimatePage,没有的话可以先注释对应跳转代码 class MetamorphicAnimatePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold(appBar: AppBar(title: Text("Metamorphic"))); } } class Filter extends StatefulWidget { @override _FilterState createState() => _FilterState(); } class _FilterState extends State<Filter> { // 初始化selected为null,满足默认无选中的需求 int? selected; @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.fromLTRB(0, 10, 0, 5), padding: EdgeInsets.fromLTRB(10, 5, 10, 10), clipBehavior: Clip.antiAlias, decoration: BoxDecoration( color: Colors.white, ), child: Column( children: [ Row( children: [ Padding( padding: EdgeInsets.fromLTRB(10, 0, 5, 3), child: Text( 'Type Search', style: TextStyle( fontFamily: "Georgia", fontSize: 18, color: Color(0xFFA86A6A), ), ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( height: 300, alignment: Alignment.center, width: MediaQuery.of(context).size.width * .94, child: Column( children: [ TypeFilter( onPressed: onPressed, selected: selected, ), ], ), ), ], ), ], ), ); } void onPressed(int index, BuildContext context) { setState(() { selected = selected == index ? null : index; }); // 按需求在选中对应按钮的时候执行跳转 if(index == 1 && selected == 1){ Navigator.push(context, MaterialPageRoute(builder: (context) =>MetamorphicAnimatePage())); } // 其他按钮跳转逻辑可以在这里按索引扩展 } } class TypeFilter extends StatelessWidget { // 修正构造函数名和类名一致 const TypeFilter({ Key? key, required this.onPressed, required this.selected, }) : super(key: key); final void Function(int selectedIndex, BuildContext context) onPressed; final int? selected; @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 移除所有放在children里的非Widget元素,只保留三个按钮,保证尺寸一致 children: [ TypeFilterButton('Igneous', 0, context), TypeFilterButton('Metamorphic', 1, context), TypeFilterButton('Sedimentary', 2, context), ], ); } Widget TypeFilterButton(String textData, int index, BuildContext context) { return GestureDetector( onTap: () => onPressed(index, context), child: Container( // 固定宽高保证所有按钮尺寸一致 width: 100, height: 50, alignment: Alignment.center, margin: EdgeInsets.fromLTRB(0, 0, 5, 0), padding: EdgeInsets.fromLTRB(2, 10, 2, 10), decoration: BoxDecoration( color: selected == index ? Color(0xFFA86A6A) : Color(0xFF5A2020), borderRadius: BorderRadius.all(Radius.circular(5)), ), child: Text( textData, textAlign: TextAlign.center, maxLines: 2, style: TextStyle( height: 1.2, fontFamily: 'Georgia', fontSize: 15, color: Colors.white), ), ), ); } }
修复说明
- 移除了放在
Row的children中不属于Widget的函数、funct调用等内容,仅保留三个按钮组件,解决类型不匹配报错 - 修正了构造函数名错误,新增空安全适配
- 把导航跳转逻辑整合到按钮的点击回调中,点击对应按钮切换选中状态的同时触发跳转
- 给按钮固定了宽高,保证三个按钮尺寸完全一致
- 默认
selected为null,符合默认无选中、展示全部内容的需求
内容的提问来源于stack exchange,提问作者dstacklurker
相关产品推荐
相关产品推荐

