Flutter中如何处理可空Widget参数并设置默认返回值
问题修复方案
Dart的类型提升机制仅对局部变量生效,对类的可空实例字段无效。即便你已经提前做了非空判断,编译器仍然无法确定这两个字段在判断后不会被修改,因此不会将其自动提升为非空Widget类型,触发返回类型不匹配的报错。
方案1:空合并运算符简化实现(最简适配)
直接用??空合并运算符设置 fallback 值,可空参数不为空时返回自身,为空时默认返回大屏布局,无需额外写if判断:
@override Widget build(BuildContext context) { return LayoutBuilder( builder:(context,constraints) { double _width = constraints.maxWidth; if(_width >= largeScreenSize) { return largeScreen; } else if (_width >= mediumScreenSize) { // 中屏布局为空就用大屏布局 return mediumScreen ?? largeScreen; } else { // 小屏布局为空就用大屏布局 return smallScreen ?? largeScreen; } } ); }
方案2:局部变量承接(官方推荐无强制解包写法)
如果不想使用特殊运算符,可以先将可空字段赋值给局部变量,Dart会对局部变量自动做类型提升,无需强制解包符即可正常返回:
@override Widget build(BuildContext context) { return LayoutBuilder( builder:(context,constraints) { double _width = constraints.maxWidth; // 赋值给局部变量,支持类型提升 final medium = mediumScreen; final small = smallScreen; if(_width >= largeScreenSize) { return largeScreen; } else if (_width >= mediumScreenSize) { if (medium != null) return medium; return largeScreen; } else { if (small != null) return small; return largeScreen; } } ); }
修改后完整组件代码
import 'package:flutter/material.dart'; const int largeScreenSize=1366; const int mediumScreenSize=768; const int smallScreenSize=360; class ResponsiveWidget extends StatelessWidget { final Widget largeScreen; final Widget? mediumScreen; final Widget? smallScreen; const ResponsiveWidget( {Key? key, required this.largeScreen, this.mediumScreen, this.smallScreen}) : super(key: key); static bool isSmallScreen(BuildContext context)=> MediaQuery.of(context).size.width<smallScreenSize; static bool isMediumScreen(BuildContext context)=> MediaQuery.of(context).size.width>=mediumScreenSize && MediaQuery.of(context).size.width<largeScreenSize; static bool isLargeScreen(BuildContext context)=> MediaQuery.of(context).size.width>=largeScreenSize; @override Widget build(BuildContext context) { return LayoutBuilder( builder:(context,constraints) { double _width=constraints.maxWidth; if(_width>=largeScreenSize) { return largeScreen; } else if (_width>=mediumScreenSize) { return mediumScreen ?? largeScreen; } else { return smallScreen ?? largeScreen; } } ); } }
内容的提问来源于stack exchange,提问作者MCB
相关产品推荐
相关产品推荐

