以编程方式显示/隐藏Flutter中的小部件

问题描述 投票:37回答:11

在Android中,每个View子类都有一个setVisibility()方法,可用于修改View对象的可见性

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

  • 可见:使View呈现在布局内可见
  • 不可见:隐藏View,但留下的间隙等于View在可见时将占据的位置
  • 消失:隐藏View,并将其完全从布局中删除。好像其heightwidth0dp

Flutter中的小部件是否具有与上述等同的功能?

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

flutter dart flutter-layout
11个回答
27
投票

更新:自从写了这个答案以来,Visibility被引入,并为该问题提供了最佳解决方案。


您可以将VisibilityOpacityopacity:一起使用来绘制使元素隐藏但仍占据空间。

为了不占用空间,请用空白的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), ))


0
投票

正如@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('');
                  },),
                ),
              ),
            ),
          ),
          ),

-4
投票

一种解决方案是将窗口小部件的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"
            )
          ],
        ),
      )
    ]))

57
投票

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

41
投票

与问题协作并显示用空的Column( children: <Widget>[ if (show) Text("This can be visible/not depending on condition"), Text("This is always visible"), ], ) 替换示例。


14
投票

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个小部件之间切换。


3
投票

flutter 1.5]和Dart 2.3


2
投票

尝试“后台”窗口小部件如果属性offstage:true,则不占用物理空间且不可见,如果属性offstage:false,它将占用物理空间并且可见


1
投票

对于初学者也可以尝试。


1
投票

更新


1
投票
© www.soinside.com 2019 - 2024. All rights reserved.