Bir Flutter Widget'ın (Merkez Widget) alt özniteliğinde koşullu ifade nasıl kullanılır


117

Şimdiye kadar, bir Widget içinde bir koşullu ifade kullanmam gerektiğinde, aşağıdakileri yaptım (Merkezi ve Kapsayıcıları basitleştirilmiş kukla örnekler olarak kullanarak):

new Center(
  child: condition == true ? new Container() : new Container()
)

Bir if / else ifadesini kullanmayı denediğimde, bir Ölü kod uyarısına yol açacaktı:

new Center(
  child: 
    if(condition == true){
      new Container();
    }else{
      new Container();
    }
)

İlginçtir ki, bir switch case deyimi ile denedim ve bana aynı uyarıyı veriyor ve bu yüzden kodu çalıştıramıyorum. Yanlış bir şey mi yapıyorum yoksa ölü kod olduğunu düşünmeden if / else kullanamaz veya flutter ifadeleri değiştiremez mi?


1
Widget'ların somutlaştırılması gereken bir blok eklemek istiyorsanız, muhtemelen widget'ınızı sınıf yöntemlerinde daha iyi oluşturmalısınız
aziza

Merkez (alt: Builder (oluşturucu: (bağlam) {if (true) return widget1 (); else return widget2 ();}))
Avnish kumar

Yanıtlar:


132

Aslında yapabilirsiniz kullanmak if/elseve switchve dart / flatteri başka deyim satır içi.

Anında anonim bir işlev kullanın

class StatmentExample extends StatelessWidget {
  Widget build(BuildContext context) {
    return Text((() {
      if(true){
        return "tis true";}

      return "anything but true";
    })());
  }
}

yani ifadelerinizi bir fonksiyona sarın

(() {
  // your code here
}())

Doğrudan UI 'işaretlemenize' çok fazla mantık koymamayı şiddetle tavsiye ederim, ancak Dart'taki tür çıkarımının biraz çalışma gerektirdiğini buldum, bu nedenle bazen böyle senaryolarda yararlı olabilir.

Üçlü operatörü kullanın

condition ? Text("True") : null,

Koleksiyonlarda If veya For ifadelerini veya yayılma operatörlerini kullanın

children: [
  ...manyItems,
  oneItem,
  if(canIKickIt)
    ...kickTheCan
  for (item in items)
    Text(item)

Bir yöntem kullanın

child: getWidget()

Widget getWidget() {
  if (x > 5) ...
  //more logic here and return a Widget

Anahtar ifadesini yeniden tanımlayın

Üçlü operatöre başka bir alternatif olarak, aşağıdaki https://stackoverflow.com/a/57390589/1058292 yazısında olduğu gibi switch ifadesinin bir işlev sürümünü oluşturabilirsiniz .

  child: case2(myInput,
  {
    1: Text("Its one"),
    2: Text("Its two"),
  }, Text("Default"));

9
Bence bu en eksiksiz cevap, teşekkürler @orangesherbert
Oniya Daniel

2
Herhangi biri takılırsa, genel durum değişikliğinde widget'larınızı yeniden oluşturmak için Sağlayıcı'yı kullanıyorsanız ve "Provider.of" aracılığıyla veri alıyorsanız, başka bir eylem widget'ınızı yeniden oluşturana kadar koşullu ifadeniz yeniden değerlendirilmeyebilir. . Koşullu değişkeninizi Widget oluşturma işlevine döndürülen "Tüketici" aracılığıyla almanız gerekir, ardından koşullu ifadeniz genel durum değişiklikleri olarak uygun şekilde yeniden değerlendirilmelidir.
Matthew Rideout

Dart / flutter'daki iyi uygulamalar için en iyi şeylerden biri
Kohls

72

Dart olarak, if/elseve switchifadeleri değil ifadelerdir. Bir değer döndürmezler, bu yüzden onları yapıcı parametrelerine geçiremezsiniz. Derleme yönteminizde çok fazla koşullu mantığınız varsa, denemek ve basitleştirmek iyi bir uygulamadır. Örneğin, kendi kendine yeten mantığı yöntemlere taşıyabilir ve if/elsedaha sonra kullanabileceğiniz yerel değişkenleri başlatmak için ifadeler kullanabilirsiniz.

Bir yöntem ve if / else kullanma

Widget _buildChild() {
  if (condition) {
    return ...
  }
  return ...
}

Widget build(BuildContext context) {
  return new Container(child: _buildChild());
}

Bir if/else

Widget build(BuildContext context) {
  Widget child;
  if (condition) {
    child = ...
  } else {
    child = ...
  }
  return new Container(child: child);
}

1
Bu doğru cevap olmalı! Bu açıklama için teşekkür ederim bana yardımcı oldu!
Slamit

31

Kayıt için Dart 2.3, Koleksiyon değişmezlerinde if / else ifadelerini kullanma özelliğini ekledi. Bu şimdi şu şekilde yapılır:

return Column(children: <Widget>[
  Text("hello"),
  if (condition)
     Text("should not render if false"),
  Text("world")
],);

Flutter Sayı # 28181 - Listede satır içi koşullu oluşturma


Dart 2.5'im var ama kodun üstünde çalışırken hata alıyorum. Bu kodun önceki sürümlerle uyumlu olması gerektiğini söylüyor. SDK kısıtlamalarını güncellemeyi dene
19'da

emmm

Döngü özelliği ekliyorlar mı? eğer öyleyse nasıl uygulanmalı?
princebillyGK


AppBar -> leading:Veya gibi tek bir widget ile çalışmıyorchild:
Alex Vang

26

Diğer cevaplar bundan bahsetmiyor, ayrıca şunları da yapabilirsiniz:

Oluşturucu widget'ını kullanın

Widget Oluşturucu Bir çocuk gereklidir Widget bir kapağın kullanılmasına izin içindir:

Alt parçacığını elde etmek için bir kapanış çağıran platonik bir parçacık.

Bir pencere öğesi oluşturmak için mantığa her ihtiyaç duyduğunuzda kullanışlıdır , özel bir işlev oluşturma ihtiyacını ortadan kaldırır. Ayrıca, anonim bir işlev kullanmaya kıyasla neyin daha net hale getirildiğini görüyorum.

Oluşturucu pencere aracını alt öğe olarak kullanırsınız ve mantığınızı builderyönteminde sağlarsınız. Örneğiniz şöyle:

Center(
  child: Builder(
    builder: (context) {
      if (condition) {
        return Container();
      } else {
        return Center();
      }
    }
  )
)

Böyle önemsiz bir örnekte üçlü operatör yeterli olacaktır ( child: condition ? Container() : Center()), ancak daha fazla mantık gerekiyorsa, Oluşturucu onu tutmak için uygun bir yer sağlar.

Ayrıca, diğer posterlerle mantığın UI kodundan çıkarılması gerektiği konusunda hemfikirim, ancak oluşturulacak parçacığı belirlemek için yalnızca bir switchveya if/ elseifadesi kullanıldığında, onu orada tutmayı tercih ederim (koşulun basit olması koşuluyla, örneğin bir ViewModel'deki değer). Builder pencere öğesi bu konuda yardımcı olabilir.


bu benim için oldukça iyi çalıştı, çekmece öğeleri tıklama ve güncelleme gövdesi için
Hızlı öğrenci

22

Flutter UI oluşturmak için koşullu mantığı kullanmanın kolay bir yolunun mantığı UI dışında tutmak olduğunu öğrendim. İşte iki farklı rengi döndürmek için bir işlev:

Color getColor(int selector) {
  if (selector % 2 == 0) {
    return Colors.blue;
  } else {
    return Colors.blueGrey;
  }
}

İşlev, CircleAvatar'ın arka planını ayarlamak için aşağıda kullanılır.

new ListView.builder(
  itemCount: users.length,
  itemBuilder: (BuildContext context, int index) {
    return new Column(
      children: <Widget>[
        new ListTile(
          leading: new CircleAvatar(
            backgroundColor: getColor(index),
            child: new Text(users[index].name[0])
          ),
          title: new Text(users[index].login),
          subtitle: new Text(users[index].name),
        ),
        new Divider(height: 2.0),
      ],
    );
  },
);

Renk seçici işlevinizi çeşitli widget'larda yeniden kullanabileceğiniz için çok temiz.


1
Bunu denedim ve benim için tam olarak çalıştım. Teşekkürler
Ajay Kumar

17

Sadece koşullu bir ifade kullanabilirsiniz a==b?c:d

Örneğin :

Container(
  color: Colors.white,
  child: ('condition')
  ? Widget1(...)
  : Widget2(...)
)

Umarım anladınız.

Başka koşul yoksa SizedBox.shrink () kullanabileceğinizi varsayalım.

Container(
      color: Colors.white,
      child: ('condition')
       ? Widget1(...)
       : SizedBox.shrink()
    )

Eğer sütun ise ?:operatör yazmaya gerek yok

Column(
 children: <Widget>[
  if('condition')
    Widget1(...),
 ],
)

1
Ya başka bir koşul yoksa? Sütunlarda, a == b? C: null
demek

1
İkinci widget olarak SizedBox.shrick () 'i kullanabilirsiniz. cevabı güncelleme.
Afinas EM

1
Eğer bir sütun ise, if koşulunu else durumu olmadan doğrudan kullanabilirsiniz: `if ('koşul') widget'ı () '
Afinas EM

16

Bu tür blok ifadelerine sahip çocuklarda şahsen if / else ifadesini kullanıyorum. Yalnızca yukarıdaki Dart 2.3.0 sürümünü destekler.

eğer / değilse

Column(
    children: [
        if (_selectedIndex == 0) ...[
          DayScreen(),
        ] else ...[
          StatsScreen(),
        ],
    ],
 ),

eğer / değilse eğer

Column(
    children: [
        if (_selectedIndex == 0) ...[
          DayScreen(),
        ] else if(_selectedIndex == 1)...[
          StatsScreen(),
        ],
    ],
 ),

1
Bu güzel ve sağlam. Teşekkürler.
jacvalle

10

İşte çözüm. Ben düzelttim. İşte kod

child: _status(data[index]["status"]),

Widget _status(status) {
  if (status == "3") {
    return Text('Process');
  } else if(status == "1") {
    return Text('Order');
  } else {
    return Text("Waiting");
  }
}

Nasıl kullanılır
ardi

6

bir widget listesi kullanıyorsanız, bunu kullanabilirsiniz:

class HomePage extends StatelessWidget {
  bool notNull(Object o) => o != null;
  @override
  Widget build(BuildContext context) {
    var condition = true;
    return Scaffold(
      appBar: AppBar(
        title: Text("Provider Demo"),
      ),
      body: Center(
          child: Column(
        children: <Widget>[
          condition? Text("True"): null,
          Container(
            height: 300,
            width: MediaQuery.of(context).size.width,
            child: Text("Test")
          )
        ].where(notNull).toList(),
      )),
    );
  }
}

durum? Text ("True"): null, bu bir hata veriyor Konsolda Asertion false, çalışma zamanı çalıştırmasında
exequielc

@exequielc .where (notNull) .toList () ve WidgetList'in sonuna ve bool notNull (Object o) => o! = null; Bütün örneği deneyin ...
wwwwwwwwwwwwww

1
Dart 2.3'ten itibaren bir listeye koşullu olarak bir widget eklemek için şunları kullanabilirsiniz: [Metin ("Merhaba"), if (dünya) Metin ("Dünya")]
Brett Sutton

4

Başka bir alternatif: switch'sbirçok koşulda benzer ifadeler için haritaları kullanmayı seviyorum:

return Card(
        elevation: 0,
        margin: EdgeInsets.all(1),
        child: conditions(widget.coupon)[widget.coupon.status] ??
            (throw ArgumentError('invalid status')));


conditions(Coupon coupon) => {
      Status.added_new: CheckableCouponTile(coupon.code),
      Status.redeemed: SimpleCouponTile(coupon.code),
      Status.invalid: SimpleCouponTile(coupon.code),
      Status.valid_not_redeemed: SimpleCouponTile(coupon.code),
    };

Koşullu ifadeye dokunmadan koşul listesine öğe eklemek / kaldırmak daha kolaydır.

Başka bir örnek:

var condts = {
  0: Container(),
  1: Center(),
  2: Row(),
  3: Column(),
  4: Stack(),
};

class WidgetByCondition extends StatelessWidget {
  final int index;
  WidgetByCondition(this.index);
  @override
  Widget build(BuildContext context) {
    return condts[index];
  }
}


2

Uygulama Örneği:

Bir düğme ile

bool _paused = false;

CupertinoButton(
  child: _paused ? Text('Play') : Text('Pause'),
  color: Colors.blue,
  onPressed: () {
    setState(() {
      _paused = !_paused;
    });
  },
),

1

**** Koşulları bu yöntemi kullanarak da kullanabilirsiniz ** **

 int _moneyCounter = 0;
  void _rainMoney(){
    setState(() {
      _moneyCounter +=  100;
    });
  }

new Expanded(
          child: new Center(
            child: new Text('\$$_moneyCounter', 

            style:new TextStyle(
              color: _moneyCounter > 1000 ? Colors.blue : Colors.amberAccent,
              fontSize: 47,
              fontWeight: FontWeight.w800
            )

            ),
          ) 
        ),

1

Bu harika bir makale ve sohbet. Üçlü operatörü açıklandığı gibi kullanmaya çalıştım. Ancak kod çalışmadı ve belirtildiği gibi bir hatayla sonuçlandı.

Column(children: [ condition? Text("True"): null,],);

Yukarıdaki üçlü örnek, yanlış liderliktir. Dart, widget yerine bir boş değer döndürüldüğünü belirten bir hata ile yanıt verir. Null döndüremezsiniz. Doğru yol, bir widget döndürmek olacaktır:

Column(children: [ condition? Text("True"): Text("false"),],); 

Üçlü sayının çalışması için bir Widget'ı iade etmeniz gerekir. Herhangi bir şeyi iade etmek istemiyorsanız, boş bir konteyner iade edebilirsiniz.

Column(children: [ condition? Text("True"): Container(),],); 

İyi şanslar.


1

Flutter'da koşullu render yapmak istiyorsanız şunu yapabilirsiniz:

Column(
   children: <Widget>[
     if (isCondition == true)
        Text('The condition is true'),
   ],
 );

Peki ya üçüncül (eğer-değilse) bir koşul kullanmak istiyorsanız? alt pencere öğesi çok katmanlı olduğunda.

Bunu, koşullu oluşturmayı geliştiren, if- else'i destekleyen ve koşulları değiştiren flutter_conditional_rendering çözümü için kullanabilirsiniz .

If-Else koşulu:

Column(
      children: <Widget>[
        Conditional.single(
          context: context,
          conditionBuilder: (BuildContext context) => someCondition == true,
          widgetBuilder: (BuildContext context) => Text('The condition is true!'),
          fallbackBuilder: (BuildContext context) => Text('The condition is false!'),
        ),
      ],
    );

Anahtar durumu:

Column(
      children: <Widget>[
        ConditionalSwitch.single<String>(
          context: context,
          valueBuilder: (BuildContext context) => 'A',
          caseBuilders: {
            'A': (BuildContext context) => Text('The value is A!'),
            'B': (BuildContext context) => Text('The value is B!'),
          },
          fallbackBuilder: (BuildContext context) => Text('None of the cases matched!'),
        ),
      ],
    );

(List<Widget>)Tek bir tane yerine bir widget listesini koşullu olarak oluşturmak istiyorsanız . Kullanım Conditional.list()veConditionalSwitch.list()!


1

Aylarca kullandıktan sonra Lol?: Bunu kullanabileceğimi öğrendim:

Column(
     children: [
       if (true) Text('true') else Text('false'),
     ],
   )

1

Dartta koşullu ifadeler için üçlü operatörü kullanabilirsiniz, kullanımı basittir

(condition) ? statement1 : statement2

eğer conditiondoğruysa, statement1aksi takdirde yürütülecektir statement2.

Pratik bir örnek almak

Center(child: condition ? Widget1() : Widget2())

Kullanmak için gidiyoruz eğer hatırla nullolarak Widget2kullanmak daha iyidir SizedBox.shrink()bazı ana widget'ları bir aldıktan sonra bir istisna çünkü nullçocuk.


0

Uygulamamda WidgetChooser, koşullu mantık olmadan widget'lar arasında seçim yapabilmek için bir widget oluşturdum :

WidgetChooser(
      condition: true,
      trueChild: Text('This widget appears if the condition is true.'),
      falseChild: Text('This widget appears if the condition is false.'),
    );

Bu, WidgetChooserwidget'ın kaynağıdır :

import 'package:flutter/widgets.dart';

class WidgetChooser extends StatelessWidget {
  final bool condition;
  final Widget trueChild;
  final Widget falseChild;

  WidgetChooser({@required this.condition, @required this.trueChild, @required this.falseChild});

  @override
  Widget build(BuildContext context) {
    if (condition) {
      return trueChild;
    } else {
      return falseChild;
    }
  }
}

-3

Yalnızca titreşimli widget ise

if(bool = true) Container(

child: ....

),

OR

if(bool = true) Container(

child: ....

) else new Container(child: lalala),
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.