Flutter'da programlı olarak widget'ları göster / gizle


135

Android'de, her bir Viewalt sınıfın setVisibility()bir Viewnesnenin görünürlüğünü değiştirmenize izin veren bir yöntemi vardır.

Görünürlüğü ayarlamak için 3 seçenek vardır:

  • Görünür: ViewDüzenin içindeki görünürlüğü işler
  • Görünmez: Gizler View, ancak Viewgörünür olsaydı kaplayacağı şeye eşdeğer bir boşluk bırakır
  • Gitti: Öğeyi gizler Viewve düzenden tamamen kaldırır. Sanki onun heightve widthöyleymiş gibi0dp

Flutter'daki Widget'lar için yukarıdakine eşdeğer bir şey var mı?

Hızlı başvuru için: https://developer.android.com/reference/android/view/View.html#attr_android:visibility

Yanıtlar:


90

GÜNCELLEME: Bu cevap yazıldığından beri Visibilitytanıtıldı ve bu soruna en iyi çözümü sağlıyor.


Bir öğeyi gizlemek ama yine de yer kaplamak için Opacitybir opacity:of ile kullanabilirsiniz 0.0.

Yer kaplamaması için boş ile değiştirin Container().

DÜZENLE: Bir Opacity nesnesine sarmak için aşağıdakileri yapın:

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

Opacity hakkında Google Developers hızlı eğitimi: https://youtu.be/9hltevOHQBw


3
Teşekkür ederim! Evet, bunu yapmanın en temiz yolu bu değil, ama kesinlikle amacına ulaşacak. Gelecekte widget'larla entegre bir görünürlük işlevine sahip olma şansınız var mı?
user3217522

4
Widget normalde kullanıcı girdisine tepki veriyorsa, onu da içine IgnorePointeraldığınızdan emin olun , aksi takdirde kullanıcı yine de tetikleyebilir.
Duncan Jones

1
Widget hala orada olduğundan ve dokunmalara yanıt verebildiğinden bu ideal değildir. Bunu halletmenin en iyi yolu için Görünürlük widget'ını kullanarak aşağıdaki yanıta bakın.
Russell Zornes

Yorumların yukarı doğru söylediği gibi, opaklık kullanmak Widget'ı renderTree'de oluşturacaktır, bazı durumlarda istediğiniz şey değildir. Görünürlük widget'ının kullanılması en çok tavsiye edilir.
Isac Moura

Bir parçacığı görünmez yapmak ve opaklığa sahip olmak iki farklı şeydir. Görünmez bir widget ile, onunla yine de etkileşimde bulunabilirsiniz, sadece görünmezdir. Görünürlük pencere öğesi, gerekene kadar pencere öğesini kaldırmanıza olanak tanır.
UndercoverCoder

203

Görünmez : Widget, ekranda fiziksel alan kaplar ancak kullanıcı tarafından görülmez.

Gitti : Widget herhangi bir fiziksel alan kaplamaz ve tamamen kaybolur.


Görünmez örnek

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

Örnek gitti

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

Alternatif olarak, ifhem görünmez hem de gitmiş için koşul kullanabilirsiniz .

Column(
  children: <Widget>[
    if (show) Text("This can be visible/not depending on condition"),
    Text("This is always visible"),
  ],
) 

21
Bu 'eğer' koşulu mükemmel!
johnc

burada başka durum nasıl kullanılır?
Hızlı öğrenen

@Quicklearner Kullanabilirsinizif(show) Text('Showing) else Text('Not showing)
CopsOnRoad

64

Soru ile işbirliği yapmak ve onu boş bir soru ile değiştirmenin bir örneğini göstermek Container().

İşte aşağıdaki örnek:

görüntü açıklamasını buraya girin

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

6
Kabul edilen cevap bu olmalıdır. Bu, "programlı olarak widget'ları göster / gizle" nin doğru uygulamasıdır
Bishwajyoti Roy

Evet, bu kesinlikle kabul edilmelidir çünkü bu, Flutter'ın bir temel sütununu kullanır, yani setState () ... aksi takdirde, Stateful widget'ınızda Visible / InVisible arasında başka nasıl gidip gelebilirsiniz!?.
Yo Apps

31

Flutter artık widget'ları göstermek / gizlemek için kullanmanız gereken bir Görünürlük Widget'ı içeriyor . Widget, değiştirmeyi değiştirerek 2 widget arasında geçiş yapmak için de kullanılabilir.

Bu widget, görünür, görünmez, kaybolan durumlardan herhangi birini ve daha fazlasını gerçekleştirebilir.

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

21

OffstageWidget'ı deneyin

offstage:truefiziksel alanı kaplamayan ve görünmez nitelikte ise,

öznitelik offstage:falsefiziksel alanı kaplar ve görünür

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

Bununla ilgili not: Flutter belgelerinin durumu, "Offstage, bir widget'ı ekrana getirmeden boyutlarını ölçmek için kullanılabilir (henüz). Gerekli olmadığında bir widget'ı görünümden gizlemek için, widget'ı ağaçtan tamamen kaldırmayı tercih edin onu bir Offstage alt ağacında canlı tutmak yerine. "
lukeic

13

Kodunuzdaki herhangi bir widget'ı (Görünürlük) adlı yeni bir widget ile kapsülleyebilirsiniz; bu, widget'ın en sol tarafındaki görünmez olmasını istediğiniz sarı lambadır.

örnek: bir satırı görünmez yapmak istediğinizi söyleyin:

  1. Lambaya tıklayın ve (Widget ile sar) öğesini seçin
  2. Widget'ı Görünürlük olarak yeniden adlandırın
  3. Visible özelliğini ekleyin ve false olarak ayarlayın
  4. Yeni oluşturulan widget'ın (Görünürlük Widget'ı) Alt Öğesi, görünmez olmasını istediğiniz Widget'tır.

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

Umarım gelecekte birine yardımcı olur


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

Gelen flutter 1.5 ve Dart 2.3 görünürlük gitmiş için, Sen konteynerlerin faydalanmak zorunda kalmadan koleksiyonu içinde bir eğer deyimi kullanarak görünürlüğünü ayarlayabilirsiniz.

Örneğin

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

          ],
        )

Bu, önceki flutter / dart sürümündeki seçeneklerden çok daha iyidir.
Hammer

5

Yeni başlayanlar için bunu da deneyin.

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";
      }
    });
  }
}

5

Güncelleme

Flutter artık bir Görünürlük parçacığına sahip. Kendi çözümünüzü uygulamak için aşağıdaki kodla başlayın.


Kendiniz bir widget oluşturun.

göster / gizle

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

göster / kaldır

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

Bu arada, yukarıdaki widget'lar için daha iyi bir adı olan var mı?

Daha Fazla Okuma

  1. Görünürlük widget'ının nasıl oluşturulacağına ilişkin makale .

3

@CopsOnRoad tarafından zaten vurgulandığı gibi, Görünürlük widget'ını kullanabilirsiniz. Ancak, durumunu korumak istiyorsanız, örneğin, bir görüntüleyici oluşturmak ve sayfaya göre belirli bir düğmenin görünmesini ve kaybolmasını istiyorsanız, bunu bu şekilde yapabilirsiniz.

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

0

Belki Navigator işlevini bu şekilde kullanabilirsiniz Navigator.of(context).pop();


-8

Çözümlerden biri, tis widget color özelliğini Colors.transparent olarak ayarlamaktır. Örneğin:

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

1
İyi bir çözüm değil çünkü şeffaf IconButtonhala tıklama alıyor ve yer kaplıyor. İnsanlar olumsuz oy kullanmadan önce bu yanıtı lütfen düzenleyin veya silin.
CopsOnRoad
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.