在Android中,每个View
子类都有一个setVisibility()
方法,可用于修改View
对象的可见性
有3种设置可见性的选项:
View
呈现在布局内可见View
,但留下的间隙等于View
在可见时将占据的位置View
,并将其完全从布局中删除。好像其height
和width
是0dp
Flutter中的小部件是否具有与上述等同的功能?
快速参考:https://developer.android.com/reference/android/view/View.html#attr_android:visibility
更新:自从写了这个答案以来,Visibility
被引入,并为该问题提供了最佳解决方案。
您可以将Visibility
与Opacity
的opacity:
一起使用来绘制使元素隐藏但仍占据空间。
为了不占用空间,请用空白的0.0
替换。
编辑:要将其包装在Opacity对象中,请执行以下操作:
Container()
关于不透明度的Google Developers快速教程: new Opacity(opacity: 0.0, child: new Padding(
padding: const EdgeInsets.only(
left: 16.0,
),
child: new Icon(pencil, color: CupertinoColors.activeBlue),
))
正如@CopsOnRoad突出显示的那样,您可以使用“可见性”小部件。但是,例如,如果您想保持其状态,则要构建一个viewpager并使某个按钮根据页面显示和消失,可以通过这种方式进行]
bool _visible = false;
void _toggle() {
setState(() {
_visible = !_visible;
});
}
onPressed: _toggle,
Visibility(
visible:_visible,
child: new Container(
child: new Container(
padding: EdgeInsets.fromLTRB(15.0, 0.0, 15.0, 10.0),
child: new Material(
elevation: 10.0,
borderRadius: BorderRadius.circular(25.0),
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search for brands and products', border: InputBorder.none,),
onChanged: onSearchTextChanged,
),
trailing: new IconButton(icon: new Icon(Icons.cancel), onPressed: () {
controller.clear();
onSearchTextChanged('');
},),
),
),
),
),
),
一种解决方案是将窗口小部件的color属性设置为Colors.transparent。例如:
void checkVisibilityButton() {
setState(() {
isVisibileNextBtn = indexPage + 1 < pages.length;
});
}
Stack(children: <Widget>[
PageView.builder(
itemCount: pages.length,
onPageChanged: (index) {
indexPage = index;
checkVisibilityButton();
},
itemBuilder: (context, index) {
return pages[index];
},
controller: controller,
),
Container(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Visibility(
visible: isVisibileNextBtn == true ? true : false,
child: "your widget"
)
],
),
)
]))
Invisible:窗口小部件占用屏幕上的物理空间,但对用户不可见。
Gone:小部件不占用任何物理空间,并且完全消失了。
不可见示例] >>
https://youtu.be/9hltevOHQBw示例
条件。Visibility( child: Text("Invisible"), maintainSize: true, maintainAnimation: true, maintainState: true, visible: false, ),
或者,您可以对不可见和消失使用
Visibility( child: Text("Gone"), visible: false, ),
if
与问题协作并显示用空的Column(
children: <Widget>[
if (show) Text("This can be visible/not depending on condition"),
Text("This is always visible"),
],
)
替换示例。
Flutter现在包含用于显示/隐藏小部件的import "package:flutter/material.dart";
void main() {
runApp(new ControlleApp());
}
class ControlleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "My App",
home: new HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
bool visibilityTag = false;
bool visibilityObs = false;
void _changed(bool visibility, String field) {
setState(() {
if (field == "tag"){
visibilityTag = visibility;
}
if (field == "obs"){
visibilityObs = visibility;
}
});
}
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(backgroundColor: new Color(0xFF26C6DA)),
body: new ListView(
children: <Widget>[
new Container(
margin: new EdgeInsets.all(20.0),
child: new FlutterLogo(size: 100.0, colors: Colors.blue),
),
new Container(
margin: new EdgeInsets.only(left: 16.0, right: 16.0),
child: new Column(
children: <Widget>[
visibilityObs ? new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Expanded(
flex: 11,
child: new TextField(
maxLines: 1,
style: Theme.of(context).textTheme.title,
decoration: new InputDecoration(
labelText: "Observation",
isDense: true
),
),
),
new Expanded(
flex: 1,
child: new IconButton(
color: Colors.grey[400],
icon: const Icon(Icons.cancel, size: 22.0,),
onPressed: () {
_changed(false, "obs");
},
),
),
],
) : new Container(),
visibilityTag ? new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Expanded(
flex: 11,
child: new TextField(
maxLines: 1,
style: Theme.of(context).textTheme.title,
decoration: new InputDecoration(
labelText: "Tags",
isDense: true
),
),
),
new Expanded(
flex: 1,
child: new IconButton(
color: Colors.grey[400],
icon: const Icon(Icons.cancel, size: 22.0,),
onPressed: () {
_changed(false, "tag");
},
),
),
],
) : new Container(),
],
)
),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new InkWell(
onTap: () {
visibilityObs ? null : _changed(true, "obs");
},
child: new Container(
margin: new EdgeInsets.only(top: 16.0),
child: new Column(
children: <Widget>[
new Icon(Icons.comment, color: visibilityObs ? Colors.grey[400] : Colors.grey[600]),
new Container(
margin: const EdgeInsets.only(top: 8.0),
child: new Text(
"Observation",
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: visibilityObs ? Colors.grey[400] : Colors.grey[600],
),
),
),
],
),
)
),
new SizedBox(width: 24.0),
new InkWell(
onTap: () {
visibilityTag ? null : _changed(true, "tag");
},
child: new Container(
margin: new EdgeInsets.only(top: 16.0),
child: new Column(
children: <Widget>[
new Icon(Icons.local_offer, color: visibilityTag ? Colors.grey[400] : Colors.grey[600]),
new Container(
margin: const EdgeInsets.only(top: 8.0),
child: new Text(
"Tags",
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: visibilityTag ? Colors.grey[400] : Colors.grey[600],
),
),
),
],
),
)
),
],
)
],
)
);
}
}
。通过更改替换,该小部件还可以用于在2个小部件之间切换。
在flutter 1.5]和Dart 2.3
尝试“后台”窗口小部件如果属性offstage:true,则不占用物理空间且不可见,如果属性offstage:false,它将占用物理空间并且可见
对于初学者也可以尝试。