在Android中,每个单独的View子类都有一个setVisibility()方法,允许你修改View对象的可见性

有3个设置可见性的选项:

可见:在布局中显示视图 不可见:隐藏视图,但留下一个空白,相当于视图在可见时所占据的空白 消失:隐藏视图,并将其完全从布局中移除。就好像它的高和宽都是0dp

对于Flutter中的小部件,是否有与上述相同的东西?

快速参考: https://developer.android.com/reference/android/view/View.html#attr_android:visibility


当前回答

定义:

不可见:小部件占用屏幕上的物理空间,但对用户不可见。这可以使用可见度小部件来实现。

消失:小部件不占用任何物理空间,完全消失。这可以使用Visibility, if或if-else条件来实现。

无形的例子:

Visibility(
  child: Text("Invisible"),
  maintainSize: true, 
  maintainAnimation: true,
  maintainState: true,
  visible: false, 
),

例子:

Visibility(
  child: Text("Gone"),
  visible: false,
),

使用如果:

对于一个孩子: 列( 孩子们:<部件> ( Text('Good Morning'), //始终可见 if (wishOnePerson) Text(' Mr ABC'), //只有条件为真时才可见 ), ) 对于多个孩子: 列( 孩子:( Text('Good Morning'), //始终可见 如果(但愿)……[//只有当condition为true时,这些子元素才可见 文本(“ABC先生”), 文本(“DEF先生”), 文本(“某某先生”), ), ), )

使用if - else:

对于一个孩子: 列( 孩子们:<部件> ( //基于'isMorning'条件,只有一个是可见的 if (isMorning) Text('Good Morning') Text ('Good Evening'), ), ) 对于多个孩子: 列( 孩子:( //在' beforeSunset '条件下,只会显示一个子元素 if (beforeSunset)…[ 文本(“早上好”), 文本('下午好'), 其他的…[ 文本(“晚上好”), 文本('晚安'), ), ), )

其他回答

class VisibilityExample extends StatefulWidget {
  const VisibilityExample({Key? key}) : super(key: key);

  @override
  _VisibilityExampleState createState() => _VisibilityExampleState();
}

class _VisibilityExampleState extends State<VisibilityExample> {
  bool visible = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Lines'),
      ),
      body: Container(
        color: Colors.black87,
        child: Stack(alignment: Alignment.bottomCenter, children: [
          ListView(
            shrinkWrap: true,
            children: [
              Container(
                height: 200,
              ),
              InkWell(
                onTap: () {},
                onHover: (value) {
                  print(value);
                  setState(() {
                    visible = !visible;
                  });
                },
                child: Visibility(
                  maintainSize: true,
                  maintainAnimation: true,
                  maintainState: true,
                  visible: visible,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      IconButton(
                        color: Colors.white54,
                        icon: const Icon(
                          Icons.arrow_left_outlined,
                        ),
                        onPressed: () {},
                      ),
                      const SizedBox(
                        width: 5,
                      ),
                      IconButton(
                        color: Colors.white54,
                        icon: const Icon(
                          Icons.add_circle_outlined,
                        ),
                        onPressed: () {},
                      ),
                      const SizedBox(
                        width: 5,
                      ),
                      IconButton(
                        color: Colors.white54,
                        icon: const Icon(
                          Icons.remove_circle,
                        ),
                        onPressed: () {},
                      ),
                      const SizedBox(
                        width: 5,
                      ),
                      IconButton(
                        color: Colors.white54,
                        icon: const Icon(
                          Icons.arrow_right_outlined,
                        ),
                        onPressed: () {},
                      ),
                      const SizedBox(
                        width: 5,
                      ),
                      IconButton(
                        color: Colors.white54,
                        icon: const Icon(Icons.replay_circle_filled_outlined),
                        onPressed: () {},
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ]),
      ),
    );
  }
}
 

恕我直言,在Flutter中不需要可见性属性或特殊的小部件,因为如果你不需要显示小部件,就不要将其添加到小部件树中或将其替换为空小部件:

  @override
  Widget build(BuildContext context) {
    return someFlag ? Text('Here I am') : SizedBox();
  }

我认为能见度小部件存在的原因是因为很多人问:)人们习惯了由某些属性控制的元素的可见性

与问题协作,并展示一个用空Container()替换它的示例。

下面是一个例子:

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],
                          ),
                        ),
                      ),
                    ],
                  ),
                )
              ),
            ],
          )                    
        ],
      )
    );
  }
}

在flutter 1.5和Dart 2.3中,对于可视性消失,您可以在集合中使用if语句设置可见性,而不必使用容器。

e.g

child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
              Text('This is text one'),
              if (_isVisible) Text('can be hidden or shown'), // no dummy container/ternary needed
              Text('This is another text'),
              RaisedButton(child: Text('show/hide'), onPressed: (){
                  setState(() {
                    _isVisible = !_isVisible; 
                  });
              },)

          ],
        )

尝试Offstage小部件

如果属性off - stage:true则不占用物理空间且不可见,

如果属性offstage:false它将占用物理空间而可见

Offstage(
   offstage: true,
   child: Text("Visible"),
),