Bisher habe ich Folgendes getan, wenn ich eine bedingte Anweisung in einem Widget verwenden musste (Verwenden von Center und Containern als vereinfachte Dummy-Beispiele):
new Center(
child: condition == true ? new Container() : new Container()
)
Wenn ich jedoch versuchte, eine if / else-Anweisung zu verwenden, führte dies zu einer Dead-Code-Warnung:
new Center(
child:
if(condition == true){
new Container();
}else{
new Container();
}
)
Interessanterweise habe ich es mit einer switch case-Anweisung versucht, die mir dieselbe Warnung gibt und daher den Code nicht ausführen kann. Mache ich etwas falsch oder ist es so, dass man if / else- oder switch-Anweisungen nicht verwenden kann, ohne zu flattern, dass es toten Code gibt?
Antworten:
Eigentlich Sie können verwenden
if/else
undswitch
und andere Aussage Inline in dart / flattern.Verwenden Sie eine sofortige anonyme Funktion
class StatmentExample extends StatelessWidget { Widget build(BuildContext context) { return Text((() { if(true){ return "tis true";} return "anything but true"; })()); } }
dh wickeln Sie Ihre Aussagen in eine Funktion
(() { // your code here }())
Ich würde dringend empfehlen, nicht zu viel Logik direkt mit Ihrem UI-Markup zu verknüpfen, aber ich fand, dass die Typinferenz in Dart ein wenig Arbeit erfordert, sodass sie in solchen Szenarien manchmal nützlich sein kann.
Verwenden Sie den ternären Operator
condition ? Text("True") : null,
Verwenden Sie If- oder For-Anweisungen oder Spread-Operatoren in Sammlungen
children: [ ...manyItems, oneItem, if(canIKickIt) ...kickTheCan for (item in items) Text(item)
Verwenden Sie eine Methode
child: getWidget() Widget getWidget() { if (x > 5) ... //more logic here and return a Widget
Switch-Anweisung neu definieren
Als weitere Alternative zum ternären Operator können Sie eine Funktionsversion der switch-Anweisung erstellen, z. B. im folgenden Beitrag https://stackoverflow.com/a/57390589/1058292 .
child: case2(myInput, { 1: Text("Its one"), 2: Text("Its two"), }, Text("Default"));
quelle
In Dart
if/else
undswitch
sind Anweisungen keine Ausdrücke. Sie geben keinen Wert zurück, sodass Sie sie nicht an Konstruktorparameter übergeben können. Wenn Ihre Erstellungsmethode viel bedingte Logik enthält, empfiehlt es sich, diese zu vereinfachen. Beispielsweise können Sie in sich geschlossene Logik in Methoden verschieben undif/else
Anweisungen verwenden, um lokale Variablen zu initialisieren, die Sie später verwenden können.Mit einer Methode und wenn / sonst
Widget _buildChild() { if (condition) { return ... } return ... } Widget build(BuildContext context) { return new Container(child: _buildChild()); }
Verwenden eines
if/else
Widget build(BuildContext context) { Widget child; if (condition) { child = ... } else { child = ... } return new Container(child: child); }
quelle
Für den Datensatz hat Dart 2.3 die Möglichkeit hinzugefügt, if / else-Anweisungen in Collection-Literalen zu verwenden. Dies geschieht nun folgendermaßen:
return Column(children: <Widget>[ Text("hello"), if (condition) Text("should not render if false"), Text("world") ],);
Flutter Issue # 28181 - Inline-bedingtes Rendern in der Liste
quelle
AppBar -> leading:
oderchild:
Die anderen Antworten erwähnen es nicht, Sie können auch:
Verwenden Sie das Builder-Widget
Das Builder-Widget soll die Verwendung eines Abschlusses ermöglichen, wenn ein untergeordnetes Widget erforderlich ist:
Es ist immer dann praktisch, wenn Sie Logik zum Erstellen eines Widgets benötigen keine dedizierte Funktion erstellen. Ich finde auch, dass es klarer macht, was getan wird, als eine sofortige anonyme Funktion zu verwenden.
Sie verwenden das Builder-Widget als untergeordnetes Element und geben Ihre Logik in seiner
builder
Methode an. Mit Ihrem Beispiel geht es:Center( child: Builder( builder: (context) { if (condition) { return Container(); } else { return Center(); } } ) )
In einem solchen trivialen Beispiel würde der ternäre Operator ausreichen (
child: condition ? Container() : Center()
), aber wenn mehr Logik benötigt wird, bietet der Builder einen geeigneten Ort, um ihn zu halten.Ich stimme auch anderen Postern zu, dass die Logik aus dem UI-Code extrahiert werden sollte, aber wenn es nur eine
switch
oderif
/else
-Anweisung ist, die zum Bestimmen des zu erstellenden Widgets verwendet wird, ziehe ich es vor, sie dort zu belassen (vorausgesetzt, die Bedingung ist einfach, zum Beispiel das Testen von a Wert in einem ViewModel). Das Builder-Widget kann dabei helfen.quelle
Ich fand heraus, dass eine einfache Möglichkeit, bedingte Logik zum Erstellen der Flutter-Benutzeroberfläche zu verwenden, darin besteht, die Logik außerhalb der Benutzeroberfläche zu halten. Hier ist eine Funktion, um zwei verschiedene Farben zurückzugeben:
Color getColor(int selector) { if (selector % 2 == 0) { return Colors.blue; } else { return Colors.blueGrey; } }
Die folgende Funktion wird verwendet, um den Hintergrund des CircleAvatar festzulegen.
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), ], ); }, );
Sehr ordentlich, da Sie Ihre Farbauswahlfunktion in mehreren Widgets wiederverwenden können.
quelle
Ich persönlich verwende die if / else-Anweisung bei Kindern mit dieser Art von Blockanweisung. Es wird nur von Dart Version 2.3.0 unterstützt.
ansonsten
Column( children: [ if (_selectedIndex == 0) ...[ DayScreen(), ] else ...[ StatsScreen(), ], ], ),
wenn / sonst wenn
Column( children: [ if (_selectedIndex == 0) ...[ DayScreen(), ] else if(_selectedIndex == 1)...[ StatsScreen(), ], ], ),
quelle
Sie können einfach eine bedingte Anweisung verwenden
a==b?c:d
Zum Beispiel :
Container( color: Colors.white, child: ('condition') ? Widget1(...) : Widget2(...) )
Ich hoffe du hast die Idee.
Angenommen, wenn keine andere Bedingung vorliegt, können Sie eine SizedBox.shrink () verwenden.
Container( color: Colors.white, child: ('condition') ? Widget1(...) : SizedBox.shrink() )
Wenn es sich um eine Spalte handelt, muss kein
?:
Operator geschrieben werdenColumn( children: <Widget>[ if('condition') Widget1(...), ], )
quelle
Hier ist die Lösung. Ich habe es repariert. Hier ist der Code
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"); } }
quelle
Wenn Sie eine Liste von Widgets verwenden, können Sie Folgendes verwenden:
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(), )), ); } }
quelle
Eine andere Alternative: Für '
switch's
' ähnliche Aussagen mit vielen Bedingungen verwende ich gerne Karten: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), };
Es ist einfacher, Elemente zur Bedingungsliste hinzuzufügen / zu entfernen, ohne die bedingte Anweisung zu berühren.
Ein anderes Beispiel:
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]; } }
quelle
Lol nach Monaten der Verwendung ?: Ich finde gerade heraus, dass ich dies verwenden kann:
Column( children: [ if (true) Text('true') else Text('false'), ], )
quelle
Dies ist ein großartiger Artikel und ein großartiges Gespräch. Ich habe versucht, den ternären Operator wie beschrieben zu verwenden. Der Code funktionierte jedoch nicht und führte wie erwähnt zu einem Fehler.
Column(children: [ condition? Text("True"): null,],);
Das obige ternäre Beispiel ist Miss Leading. Dart antwortet mit dem Fehler, dass anstelle des Widgets eine Null zurückgegeben wurde. Sie können nicht null zurückgeben. Der richtige Weg ist, ein Widget zurückzugeben:
Column(children: [ condition? Text("True"): Text("false"),],);
Damit das Ternär funktioniert, müssen Sie ein Widget zurückgeben. Wenn Sie nichts zurückgeben möchten, können Sie einen leeren Container zurückgeben.
Column(children: [ condition? Text("True"): Container(),],);
Viel Glück.
quelle
Mit einem Knopf
bool _paused = false; CupertinoButton( child: _paused ? Text('Play') : Text('Pause'), color: Colors.blue, onPressed: () { setState(() { _paused = !_paused; }); }, ),
quelle
**** Mit dieser Methode können Sie auch Bedingungen verwenden ** **
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 ) ), ) ),
quelle
Wenn Sie im Flattern bedingtes Rendern ausführen möchten, können Sie Folgendes tun:
Column( children: <Widget>[ if (isCondition == true) Text('The condition is true'), ], );
Aber was ist, wenn Sie eine tertiäre (wenn-sonst) Bedingung verwenden möchten? wenn das untergeordnete Widget mehrschichtig ist.
Sie können dies für die Lösung flutter_conditional_rendering verwenden, ein Flatterpaket , das das bedingte Rendern verbessert, if- else- und switch-Bedingungen unterstützt.
Wenn-sonst-Bedingung:
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!'), ), ], );
Schalterbedingung:
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!'), ), ], );
Wenn Sie eine Liste von Widgets
(List<Widget>)
anstelle eines einzelnen bedingt rendern möchten . Verwenden SieConditional.list()
undConditionalSwitch.list()!
quelle
In meiner App habe ich ein
WidgetChooser
Widget erstellt, damit ich zwischen Widgets ohne bedingte Logik wählen kann:WidgetChooser( condition: true, trueChild: Text('This widget appears if the condition is true.'), falseChild: Text('This widget appears if the condition is false.'), );
Dies ist die Quelle für das
WidgetChooser
Widget: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; } } }
quelle
Sie können den ternären Operator für bedingte Anweisungen in Dart verwenden. Die Verwendung ist einfach
Wenn das
condition
wahr ist,statement1
wird das anders ausgeführtstatement2
.Ein praktisches Beispiel nehmen
Denken Sie daran, ob Sie es verwenden möchten,
null
daWidget2
es besser ist, es zu verwenden,SizedBox.shrink()
da einige übergeordnete Widgets eine Ausnahme auslösen, nachdem Sie einnull
Kind erhalten haben.quelle
Nur wenn vibrierendes Widget
if(bool = true) Container( child: .... ), OR if(bool = true) Container( child: .... ) else new Container(child: lalala),
quelle