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

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

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

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

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


当前回答

在Flutter中有很多不同的方法来实现这一点。在我解释它们之前,我将首先提供与android原生“隐形”和“消失”等价的快速解决方案:

视图。看不见的:

Opacity(
  opacity: 0.0,
  child: ...
)

视图。了:

Offstage(
  child: ...
)

现在让我们比较一下这些方法和其他方法:

不透明度

这个小部件将不透明度(alpha)设置为您想要的任何值。将其设置为0.0比设置为0.1略显不明显,所以希望这很容易理解。小部件仍将保持其大小和占用相同的空间,并保持每个状态,包括动画。由于它留下了一个间隙,用户仍然可以触摸或点击它。(顺便说一下,如果你不想让人们触摸一个看不见的按钮,你可以用一个IgnorePointer小部件来包装它。)

后台

这个小部件隐藏了子小部件。你可以把它想象成把小部件放在“屏幕外面”,这样用户就看不到它了。小部件仍然要完成颤振管道中的所有内容,直到它到达最后的“绘制”阶段,在这个阶段它根本不绘制任何东西。这意味着它将维护所有的状态和动画,但不会在屏幕上呈现任何东西。此外,它在布局时也不会占用任何空间,不会留下任何空隙,用户自然无法点击。

可见性

这个小部件结合了上述(以及更多)功能,方便您使用。它有参数,如maintainState, maintainAnimation, maintainSize, maintainInteractivity等。根据你设置这些属性的方式,它由以下决定:

if you want to maintain state, it will either wrap the child with an Opacity or with an Offstage, depends on whether you also want to maintain size. Further, unless you want to maintainInteractivity, it will also wrap an IgnorePointer for you, because clicking on a transparent button is kinda weird. if you don't want to maintainState at all, it directly replaces the child with a SizedBox so it's completely gone. You can change the blank SizedBox to anything you want, with the replacement property.

删除小部件

如果您不需要维护状态等,通常建议完全从树中删除小部件。例如,您可以使用if (condition)来决定是否将小部件包含在列表中,或者使用condition ?child: sizebox()直接用sizebox替换它。这样可以避免不必要的计算,并且对于性能来说是最好的。

其他回答

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

          ],
        )

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

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

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

尝试Offstage小部件

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

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

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

在Flutter中有很多不同的方法来实现这一点。在我解释它们之前,我将首先提供与android原生“隐形”和“消失”等价的快速解决方案:

视图。看不见的:

Opacity(
  opacity: 0.0,
  child: ...
)

视图。了:

Offstage(
  child: ...
)

现在让我们比较一下这些方法和其他方法:

不透明度

这个小部件将不透明度(alpha)设置为您想要的任何值。将其设置为0.0比设置为0.1略显不明显,所以希望这很容易理解。小部件仍将保持其大小和占用相同的空间,并保持每个状态,包括动画。由于它留下了一个间隙,用户仍然可以触摸或点击它。(顺便说一下,如果你不想让人们触摸一个看不见的按钮,你可以用一个IgnorePointer小部件来包装它。)

后台

这个小部件隐藏了子小部件。你可以把它想象成把小部件放在“屏幕外面”,这样用户就看不到它了。小部件仍然要完成颤振管道中的所有内容,直到它到达最后的“绘制”阶段,在这个阶段它根本不绘制任何东西。这意味着它将维护所有的状态和动画,但不会在屏幕上呈现任何东西。此外,它在布局时也不会占用任何空间,不会留下任何空隙,用户自然无法点击。

可见性

这个小部件结合了上述(以及更多)功能,方便您使用。它有参数,如maintainState, maintainAnimation, maintainSize, maintainInteractivity等。根据你设置这些属性的方式,它由以下决定:

if you want to maintain state, it will either wrap the child with an Opacity or with an Offstage, depends on whether you also want to maintain size. Further, unless you want to maintainInteractivity, it will also wrap an IgnorePointer for you, because clicking on a transparent button is kinda weird. if you don't want to maintainState at all, it directly replaces the child with a SizedBox so it's completely gone. You can change the blank SizedBox to anything you want, with the replacement property.

删除小部件

如果您不需要维护状态等,通常建议完全从树中删除小部件。例如,您可以使用if (condition)来决定是否将小部件包含在列表中,或者使用condition ?child: sizebox()直接用sizebox替换它。这样可以避免不必要的计算,并且对于性能来说是最好的。

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