如何在Flutter中呈现空视图,因为Widget.build无法返回null来指示没有要渲染的东西。
答案 0 :(得分:4)
这可能为时已晚,但所有这些解决方案都不适用于某些场景,例如玩 PopupMenuItems
或影响 UI 呈现!
解决方案是在传递给渲染组件之前移除空项:
Column(
children: [
Text('Title'),
name != ''
? Text(name) //show name
: null // just pass a null we will filter it in next line!
].where((e) => e != null).toList()// Filter list and make it List again!
)
这样,我们可以有很多 null 并且 UI 不会受到任何空 Widget
的影响。
PopupMenuButton
示例 我们无法传递 SizedBox 的示例:
PopupMenuButton(
icon: Icon(Icons.add),
itemBuilder: (context) => [
PopupMenuItem(
child: Row(children:[ Icon(Icons.folder), Text('So something')]),
value: 'do.something',
),
1 > 2 //⚠️ A false condition
? PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('⚠️No way to display ?')]),
'no.way.to.display',
)
: null,// ⚠️ Passing null
PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('Do something else')]),
'do.something.else',
)
].where((e) => e != null).toList(),//ℹ️ Removing null items
onSelected: (item) {}
)
这可以用作带有 extension
的 API:
extension NotNulls on List {
///Returns items that are not null, for UI Widgets/PopupMenuItems etc.
notNulls() {
return where((e) => e != null).toList();
}
}
//Usage:
PopupMenuButton(
icon: Icon(Icons.add),
itemBuilder: (context) => [
PopupMenuItem(
child: Row(children:[ Icon(Icons.folder), Text('So something')]),
value: 'do.something',
),
1 > 2 //⚠️ A false condition
? PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('⚠️No way to display ?')]),
'no.way.to.display',
)
: null,// ⚠️ Passing null
PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('Do something else')]),
'do.something.else',
)
].notNulls(),//ℹ️ Removing null items
onSelected: (item) {}
)
答案 1 :(得分:4)
容器 = 166,173 毫秒
SizedBox.shrink = 164,523 毫秒
自己动手
main() async {
testWidgets('test', (WidgetTester tester) async {
await tester.pumpWidget( Container());
final Stopwatch timer = new Stopwatch()..start();
for (int index = 0; index < 5000000; index += 1) {
await tester.pump();
}
timer.stop();
debugPrint('Time taken: ${timer.elapsedMilliseconds}ms');
});
}
答案 2 :(得分:3)
建议不显示任何内容的小部件是使用[SizedBox][1]
。
SizedBox(
width: 200.0,
height: 300.0,
child: const Card(child: Text('Hello World!')),
)
答案 3 :(得分:3)
在 Column
中,我使用的是 SizedBox(height: 0.01)
Column(
children: [
Text('Title'),
name == ''
? SizedBox(height: 0.01) // show nothing
: Text(name) // show name
]
)
答案 4 :(得分:1)
import 'package:flutter/material.dart';
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: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
);
}
}
您还可以简单地返回一个空的Container
,而避免完全使用Scaffold
。但是,如果这是您应用程序中唯一的主窗口小部件,则会导致黑屏,如果您想防止黑背景,则可以设置color
的{{1}}属性。
示例:
Container
答案 5 :(得分:1)
对于像我这样的人,想知道什么是显示空窗口小部件的“正确方法”-官方材料代码库使用以下方法:
Widget build(BuildContext context) {
return SizedBox.shrink();
}
SizedBox.shrink()
是一个小工具,与Container
或Material
不同,它没有背景或任何装饰。如果不受父约束的影响,它会自动将尺寸调整为最小。
答案 6 :(得分:1)
我的问题非常相似,但是我发现Container
和SizedBox.shrink
仍然(令人沮丧地)影响用户界面。
我最好的解决方案是使用命名构造函数和初始化列表以不同的方式构建它。例如:
class MyWidget extends StatelessWidget {
final String name = 'Default';
final bool hasThing = true;
MyWidget({this.name});
MyWidget.withoutThing({this.name}) : hasThing = false;
@override
Widget build(BuildContext context) {
//define widgets they have in common here (as many as possible)
if (hasThing) {
return Widget(child: Thing(this.name));
} else {
return Widget(child: WithoutThing(this.name));
}
}
}
并使用它:
Center(child: MyWidget.withoutThing(name: 'Foo'),)//don't show thing
或
Center(child: MyWidget(name: 'Foo'),)
根据您的需求。
有关初始化列表的更多信息:Colon after Constructor in dart
答案 7 :(得分:0)
当构建函数返回null时,来自flutter的错误消息为:
构建函数绝不能返回null。要返回使建筑物小部件填充可用空间的空白空间,请返回“ new Container()”。要返回占用尽可能少空间的空白空间,请返回“新容器(宽度:0.0,高度:0.0)”。
答案 8 :(得分:0)
有许多可能的解决方案。喜欢
Widget build(context) => Container();
Widget build(context) => SizedBox();
Widget build(context) => Scaffold();