Как использовать условный оператор в дочернем атрибуте виджета Flutter (Center Widget)
До сих пор всякий раз, когда мне нужно было использовать условный оператор внутри виджета, я сделал следующее (использование Center и Containers в качестве упрощенных фиктивных примеров):
new Center(
child: condition == true ? new Container() : new Container()
)
Хотя, когда я пытался использовать оператор if/else, это привело бы к предупреждению Dead code:
new Center(
child:
if(condition == true){
new Container();
}else{
new Container();
}
)
Интересно, что я попытался с помощью оператора case switch, и он дает мне такое же предупреждение, и поэтому я не могу запустить код. Я делаю что-то неправильно или это так, что нельзя использовать if/else или инструкции switch без трепета, думая, что есть мертвый код?
Ответы
Ответ 1
В Dart if/else
и switch
есть выражения, а не выражения. Они не возвращают значение, поэтому вы не можете передать их параметрам конструктора. Если в вашем методе сборки есть много условной логики, то это хорошая практика, чтобы попытаться ее упростить. Например, вы можете перемещать автономную логику в методы и использовать операторы if/else
для инициализации локальных переменных, которые вы можете использовать позже.
Использование метода и if/else
Widget _buildChild() {
if (condition) {
return ...
}
return ...
}
Widget build(BuildContext context) {
return new Container(child: _buildChild());
}
Использование if/else
Widget build(BuildContext context) {
Widget child;
if (condition) {
child = ...
} else {
child = ...
}
return new Container(child: child);
}
Ответ 2
На самом деле вы можете использовать if/else
и switch
и любые другие операторы, встроенные в дартс/флаттер.
Используйте немедленную анонимную функцию
class StatmentExample extends StatelessWidget {
Widget build(BuildContext context) {
return Text((() {
if(true){
return "tis true";}
return "anything but true";
})());
}
}
то есть обернуть свои утверждения в функцию
(() {
// your code here
}())
Я бы настоятельно рекомендовал не помещать слишком много логики непосредственно в разметку вашего пользовательского интерфейса, но я обнаружил, что вывод типов в Dart требует небольшой работы, поэтому иногда это может быть полезно в подобных сценариях.
Используйте троичный оператор
condition? Text("True"): null,
Использовать операторы If или For или операторы распространения в коллекциях
children: [
...manyItems,
oneItem,
if(canIKickIt)
...kickTheCan
for (item in items)
Text(item)
Используйте метод
child: getWidget()
Widget getWidget() {
if (x > 5) ...
//more logic here and return a Widget
Переопределить оператор переключения
В качестве другой альтернативы троичному оператору вы можете создать функциональную версию оператора switch, например, в следующем посте fooobar.com/questions/18291800/....
child: case2(myInput,
{
1: Text("Its one"),
2: Text("Its two"),
}, Text("Default"));
Ответ 3
Я обнаружил, что простой способ использования условной логики для создания пользовательского интерфейса Flutter - это сохранить логику вне пользовательского интерфейса. Вот функция, которая возвращает два разных цвета:
Color getColor(int selector) {
if (selector % 2 == 0) {
return Colors.blue;
} else {
return Colors.blueGrey;
}
}
Функция используется ниже для установки фона CircleAvatar.
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),
],
);
},
);
Очень удобно, так как вы можете повторно использовать функцию выбора цвета в нескольких виджетах.
Ответ 4
Вот решение. Я исправил это. Вот код
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");
}
}
Ответ 5
если вы используете список виджетов, вы можете использовать это:
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(),
)),
);
}
}
Ответ 6
Другая альтернатива: для операторов типа switch's
, с большим количеством условий, мне нравится использовать карты:
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),
};
Легче добавлять/удалять элементы в списке условий, не касаясь условного оператора.
Другой пример:
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];
}
}
Ответ 7
У меня есть проблема, связанная с оператором if в dart, я хочу, чтобы пользователь коснулся города, чтобы перейти на новый экран. этот код работает отлично
class citySec extends StatelessWidget {
Widget getListView(BuildContext context) {
var listView = ListView(
children: <Widget>[
Text(
"choose ur city:",
textDirection: TextDirection.rtl,
textAlign: TextAlign.center,
),
ListTile(
leading: Icon(Icons.location_city),
title: Text("Toronto ", textDirection: TextDirection.rtl),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TorontoUniversitySection(),
),
);
},
),
],
);
return listView;
}
@override
Widget build(BuildContext context) {
return Scaffold(body: getListView(context));
}
}
Тем не менее, у меня есть длинный список городов, и предыдущий код сделает мой код очень длинным, поэтому мне пришлось изменить код, и я столкнулся с некоторыми ошибками в операторах if, вот что я сделал до сих пор.
import 'package:flutter/material.dart';
import 'package:rate/screens/firstScreen.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Rate',
home: Scaffold(
appBar: AppBar(
title: Text("jgfnjfnj ", textDirection: TextDirection.rtl),
),
body: ListDisplay(),
),
));
}
class ListDisplay extends StatelessWidget {
List<String> litems = ["Toronto","NewYork","London","Riyadh","Dubai","Istanbul"];
@override
Widget build (BuildContext ctxt) {
return new Scaffold(
appBar: AppBar(title: Text("Please Choose your city: ", textDirection: TextDirection.ltr,),
),
body: new ListView.builder
(
itemCount: litems.length,
itemBuilder: (BuildContext ctxt, int index) {
return new ListTile(
leading: Icon(Icons.location_city),
title: Text(litems[index], textDirection: TextDirection.rtl),
onTap: () {
if (litems.contains("Totonto")){
Navigator.push(
ctxt,
MaterialPageRoute(
builder: (ctxt) => TorontoUniversitySection()
),
);
}
else if (litems.contains("London")){
Navigator.push(
ctxt,
MaterialPageRoute(
builder: (ctxt) => LondonUniversitySection()
),
);
}
},
);
}
)
);
}
}
Ответ 8
**** Вы также можете использовать условия, используя этот метод ** **
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
)
),
)
),
Ответ 9
использовать conditional_builder 1.0.2
см. ссылку ниже
кликните сюда