프로그래밍 방식으로 Flutter에서 위젯 표시 / 숨기기


112

Android에서 모든 단일 View하위 클래스에는 객체 setVisibility()의 가시성을 수정할 수 있는 메서드가 있습니다.View

가시성을 설정하는 세 가지 옵션이 있습니다.

  • Visible : View레이아웃 내부에 보이는 것을 렌더링합니다.
  • 보이지 않음 :을 숨기지 ViewView표시되는 경우 차지하는 것과 동일한 간격을 남깁니다.
  • 사라짐 :을 숨기고 View레이아웃에서 완전히 제거합니다. 그건 마치 그 heightwidth있었다0dp

Flutter의 위젯에 대해 위와 동일한 것이 있습니까?

빠른 참조 : https://developer.android.com/reference/android/view/View.html#attr_android:visibility

답변:


81

업데이트 :이 답변이 작성 되었으므로이 Visibility문제에 대한 최상의 솔루션을 제공했습니다.


당신은 사용할 수 있습니다 Opacityopacity:0.0요소가 숨겨져 있지만 여전히 공간을 차지하게 그립니다.

공간을 차지하지 않도록하려면 빈 Container().

편집 : Opacity 개체로 감싸려면 다음을 수행하십시오.

            new Opacity(opacity: 0.0, child: new Padding(
              padding: const EdgeInsets.only(
                left: 16.0,
              ),
              child: new Icon(pencil, color: CupertinoColors.activeBlue),
            ))

Opacity에 대한 Google Developers 빠른 자습서 : https://youtu.be/9hltevOHQBw


3
감사합니다! 네, 그것이 가장 깨끗한 방법은 아니지만 확실히 목적을 달성 할 것입니다. 향후 위젯과 통합 된 가시성 기능을 가질 가능성이 있습니까?
user3217522

3
위젯이 일반적으로 사용자 입력에 반응하는 경우 위젯도로 래핑해야 IgnorePointer합니다. 그렇지 않으면 사용자가 계속 트리거 할 수 있습니다.
Duncan Jones

1
위젯이 여전히 있고 탭 등에 응답 할 수 있기 때문에 이상적이지 않습니다.이를 처리하는 가장 좋은 방법은 가시성 위젯을 사용하여 아래 답변을 참조하십시오.
Russell Zornes

주석이 위쪽으로 말했듯이, 불투명도를 사용하면 renderTree에서 위젯이 렌더링되며 경우에 따라 원하는 것이 아닙니다. 가시성 위젯을 사용하는 것이 가장 좋습니다.
Isac Moura

위젯을 보이지 않게 만들고 불투명도를 0으로하는 것은 두 가지 다른 것입니다. 보이지 않는 위젯을 사용하면 여전히 상호 작용할 수 있습니다. 가시성 위젯을 사용하면 필요할 때까지 위젯을 제거 할 수 있습니다.
UndercoverCoder

173

Invisible : 위젯이 화면의 물리적 공간을 차지하지만 사용자에게는 보이지 않습니다.

사라짐 : 위젯이 물리적 공간을 차지하지 않고 완전히 사라졌습니다.


보이지 않는 예

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"),
  ],
) 

16
'만약'조건은 완벽합니다!
johnc

I love flutter ❤️
nipunasudha

62

질문과 공동 작업하고 빈으로 바꾸는 예를 보여줍니다 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],
                          ),
                        ),
                      ),
                    ],
                  ),
                )
              ),
            ],
          )                    
        ],
      )
    );
  }
}

5
이것은 받아 들여진 대답이어야합니다. 이것은 "프로그램 표시 / 숨기기 위젯 '의 올바른 구현
Bishwajyoti 로이

예, 이것은 Flutter의 기초 기둥 즉 setState ()를 사용하기 때문에 확실히 받아 들여 져야합니다.
Yo Apps

27

Flutter는 이제 가시성 위젯을 포함합니다 을 표시 / 숨기기 위해 사용해야 이 있습니다. 위젯을 사용하여 교체를 변경하여 두 위젯간에 전환 할 수도 있습니다.

이 위젯은 보이는 상태, 보이지 않는 상태, 사라진 상태 등을 달성 할 수 있습니다.

    Visibility(
      visible: true //Default is true,
      child: Text('Ndini uya uya'),
      //maintainSize: bool. When true this is equivalent to invisible;
      //replacement: Widget. Defaults to Sizedbox.shrink, 0x0
    ),

19

Offstage위젯 사용해보기

속성 offstage:true이 물리적 공간을 차지하지 않고 보이지 않는 경우,

속성 offstage:false이면 물리적 공간을 차지하고 표시됩니다.

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

참고 : Flutter 문서 상태, "Offstage를 사용하여 위젯을 화면으로 가져 오지 않고도 (아직) 위젯의 크기를 측정 할 수 있습니다. 위젯이 필요하지 않은 동안보기에서 위젯을 숨기려면 트리에서 위젯을 완전히 제거하는 것이 좋습니다. Offstage 하위 트리에서 유지하는 것보다. "
미지근한

10
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('');
                  },),
                ),
              ),
            ),
          ),
          ),

9

에서 플러터 1.5다트 2.3 가시성이 사라를 위해, 당신은 용기를 사용하지 않고도 컬렉션 내의 if 문을 사용하여 가시성을 설정할 수 있습니다.

예 :

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 / dart 버전에서 사용할 수있는 옵션보다 훨씬 낫습니다.
Hammer

8

(Visibility)라는 새 위젯을 사용하여 코드의 모든 위젯을 캡슐화 할 수 있습니다. 이는 위젯의 맨 왼쪽에있는 노란색 램프에서 표시되지 않도록 할 수 있습니다.

예 : 행을 보이지 않게 만들고 싶다고 가정합니다.

  1. 램프를 클릭하고 (Wrap with widget)을 선택하십시오.
  2. 위젯 이름을 Visibility로 변경
  3. visible 속성을 추가하고 false로 설정합니다.
  4. 새로 생성 된 위젯 (Visibility Widget)의 자식은 보이지 않게하려는 위젯입니다.

              Visibility(
                  visible: false,
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      SizedBox(
                        width: 10,
                      ),
                      Text("Search",
                        style: TextStyle(fontSize: 20
                        ),),
                    ],
                  ),
                ),

앞으로 누군가를 도울 수 있기를 바랍니다.


5

초보자도 이것을 시도하십시오.

class Visibility extends StatefulWidget {
  @override
  _VisibilityState createState() => _VisibilityState();
}

class _VisibilityState extends State<Visibility> {
  bool a = true;
  String mText = "Press to hide";

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Visibility",
      home: new Scaffold(
          body: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new RaisedButton(
                onPressed: _visibilitymethod, child: new Text(mText),),
                a == true ? new Container(
                width: 300.0,
                height: 300.0,
                color: Colors.red,
              ) : new Container(),
            ],
          )
      ),
    );
  }

  void _visibilitymethod() {
    setState(() {
      if (a) {
        a = false;
        mText = "Press to show";
      } else {
        a = true;
        mText = "Press to hide";
      }
    });
  }
}

3

최신 정보

이제 Flutter에 가시성 위젯이 있습니다. 자체 솔루션을 구현하려면 아래 코드로 시작하십시오.


직접 위젯을 만드세요.

표시 / 숨기기

class ShowWhen extends StatelessWidget {
  final Widget child;
  final bool condition;
  ShowWhen({this.child, this.condition});

  @override
  Widget build(BuildContext context) {
    return Opacity(opacity: this.condition ? 1.0 : 0.0, child: this.child);
  }
}

표시 / 제거

class RenderWhen extends StatelessWidget {
  final Widget child;
  final bool condition;
  RenderWhen({this.child, this.show});

  @override
  Widget build(BuildContext context) {
    return this.condition ? this.child : Container();
  }
}

그건 그렇고, 위의 위젯에 대해 더 나은 이름을 가진 사람이 있습니까?


더 읽기

  1. 가시성 위젯을 만드는 방법에 대한 기사 .

3

@CopsOnRoad에서 이미 강조 표시했듯이 가시성 위젯을 사용할 수 있습니다. 그러나 상태를 유지하고 싶다면, 예를 들어 뷰 페이저를 구축하고 페이지를 기반으로 특정 버튼이 나타나고 사라지도록하려면 다음과 같이 할 수 있습니다.

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"
            )
          ],
        ),
      )
    ]))


-8

한 가지 해결책은 tis 위젯 색상 속성을 Colors.transparent로 설정하는 것입니다. 예를 들면 :

IconButton(
    icon: Image.asset("myImage.png",
        color: Colors.transparent,
    ),
    onPressed: () {},
),

1
투명도가 IconButton여전히 클릭을 받고 공간을 차지 하기 때문에 좋은 솔루션이 아닙니다 . 사람들이 반대 투표하기 전에이 답변을 수정하거나 삭제하십시오.
CopsOnRoad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.