如何在颤动中呈现一个空视图?
Posted
技术标签:
【中文标题】如何在颤动中呈现一个空视图?【英文标题】:How to present an empty view in flutter? 【发布时间】:2019-04-26 13:52:14 【问题描述】:如何在 Flutter 中呈现一个空视图,因为 Widget.build 无法返回 null 以指示没有要渲染的内容。
【问题讨论】:
所以返回一个空的Containter
或 Material
或类似的小部件..
如果您需要占位符,请不要忘记有一个占位符小部件:youtube.com/watch?v=LPe56fezmoo
【参考方案1】:
对于像我这样想知道什么是显示空小部件的“正确方法”的人 - 官方 Material 代码库使用这个:
Widget build(BuildContext context)
return SizedBox.shrink();
SizedBox.shrink()
是一个与Container
或Material
不同的小部件,它没有任何背景或任何装饰。如果不受父约束的影响,它将自身调整到尽可能小的区域。
【讨论】:
基本上只返回SizedBox(width: 0, height: 0)
!
这是唯一不会在列表视图中引发错误的答案
尽管 SizedBox.shrink 很有用,但它仍然会在屏幕上占用一些空间,我宁愿说它就像 SizedBox(width: 5, height: 5)
如果您使用 Column and Row,这将不起作用,它仍将计为 col 和 row 项【参考方案2】:
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
。但是如果这是您应用中唯一的主要小部件,这将导致黑屏,如果您想防止黑背景,您可以设置Container
的color
属性。
例子:
class _MyHomePageState extends State<MyHomePage>
@override
Widget build(BuildContext context)
return Container(
color: Colors.white // This is optional
);
【讨论】:
【参考方案3】:有很多可能的解决方案。喜欢
Widget build(context) => Container();
Widget build(context) => SizedBox();
Widget build(context) => Scaffold();
【讨论】:
【参考方案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.elapsedMillisecondsms');
);
【讨论】:
哇,好研究 如果您不知道该代码放在哪里,请按双档并打开widget_test.dart
【参考方案5】:
当构建函数返回 null 时,flutter 的错误信息是:
构建函数绝不能返回 null。要返回导致建筑小部件填满可用空间的空白空间,请返回“new Container()”。要返回占用尽可能少空间的空白空间,请返回“new Container(width: 0.0, height: 0.0)”。
【讨论】:
是的。如果我在零安全方案中运行应用程序,我会遇到这个问题。所以,我选择听从你的建议。【参考方案6】:这可能为时已晚,但所有这些解决方案都不适用于某些场景,例如玩 PopupMenuItems
或影响 UI 渲染!
空安全更新
[
.
.
.
if(condition)...[//Conditionally widget(s) here
Something(...),
],
.
.
.
],
解决方案是在传递给渲染组件之前删除空项:
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!
)
这样,我们可以有很多空,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)
)
【讨论】:
【参考方案7】:不显示任何内容的推荐小部件是使用SizedBox
。
SizedBox(
width: 200.0,
height: 300.0,
)
【讨论】:
此建议的参考依据是什么? 我花了很长时间才回复,但 SizedBox 已在第一方小部件(如 AppBar)中用于显示空白内容。【参考方案8】:我的问题非常相似,但我发现 Container
和 SizedBox.shrink
仍然影响 UI(令人沮丧)。
我得到的最佳解决方案是使用命名构造函数和初始化列表以不同方式构建它。例如:
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
【讨论】:
【参考方案9】:在Column
里面我用的是SizedBox(height: 0.01)
Column(
children: [
Text('Title'),
name == ''
? SizedBox(height: 0.01) // show nothing
: Text(name) // show name
]
)
【讨论】:
以上是关于如何在颤动中呈现一个空视图?的主要内容,如果未能解决你的问题,请参考以下文章