एक स्पंदन विजेट (केंद्र विजेट) के बच्चे की विशेषता के भीतर सशर्त विवरण का उपयोग कैसे करें


130

अब तक जब भी मुझे एक विजेट के भीतर एक सशर्त विवरण का उपयोग करने की आवश्यकता होती है, तो मैंने निम्नलिखित किया है (केंद्र और कंटेनरों का सरलीकृत उदाहरणों का उपयोग करके):

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

हालाँकि जब मैंने if / if स्टेटमेंट का उपयोग करने की कोशिश की, तो यह डेड कोड चेतावनी की ओर ले जाएगा:

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

दिलचस्प बात यह है कि मैंने स्विच केस स्टेटमेंट के साथ कोशिश की और यह मुझे एक ही चेतावनी देता है और इस तरह मैं कोड नहीं चला सकता। क्या मैं कुछ गलत कर रहा हूँ या ऐसा इसलिए है कि कोई उपयोग नहीं कर सकता / रही है या बिना बयानों को बदल दिए बिना यह सोचे कि मृत कोड है?


1
यदि आप एक ऐसा ब्लॉक सम्मिलित करना चाहते हैं, जहाँ विजेट्स को त्वरित किया जाना चाहिए, तो संभवतः आप बेहतर तरीके से अपने विजेट को क्लास विधियों में बनाएँ
aziza

केंद्र (बच्चा: बिल्डर (बिल्डर: (संदर्भ) {if (सच) रिटर्न विजेट 1 (); और रिटर्न विजेट 2 ();}))
अवनीश कुमार

जवाबों:


157

वास्तव में आप डार्ट / स्पंदन में उपयोग कर सकते हैं 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
}())

मैं आपके UI 'मार्कअप' के साथ सीधे तौर पर बहुत अधिक तर्क रखने के खिलाफ जोरदार सिफारिश करूंगा, लेकिन मैंने पाया कि डार्ट में टाइप इंट्रेंस को थोड़ा काम करने की जरूरत है, इसलिए यह कभी-कभी इस तरह के परिदृश्यों में उपयोगी हो सकता है।

टर्नरी ऑपरेटर का उपयोग करें

condition ? Text("True") : null,

उपयोग करें या बयानों के लिए या संग्रह में ऑपरेटरों को फैलाने के लिए

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

पुन: परिभाषित करें स्विच स्टेटमेंट

टर्नरी ऑपरेटर के एक अन्य विकल्प के रूप में, आप स्विच स्टेटमेंट का एक फंक्शन संस्करण बना सकते हैं जैसे कि निम्नलिखित पोस्ट https://stackoverflow.com/a/57390589/1058292 पर

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

9
मेरी राय में, यह सबसे पूर्ण उत्तर है, धन्यवाद @orangesherbert
ओनिया डैनियल

2
बस एक नोट अगर किसी को अटक जाता है, यदि आप प्रदाता का उपयोग वैश्विक राज्य परिवर्तन पर अपने विजेट्स के पुनर्निर्माण के लिए कर रहे हैं, और आपको "प्रोवाइडर.ऑफ" के माध्यम से डेटा मिल रहा है, तो आपके सशर्त विवरण का पुनर्मूल्यांकन नहीं किया जा सकता जब तक कि कुछ अन्य कार्रवाई आपके विजेट का पुनर्निर्माण नहीं करती । आपको अपने कंज्यूमर वैरिएबल को "कंज्यूमर" के माध्यम से प्राप्त करना होगा जो कि विजेट बिल्ड फंक्शन में लौटाया जा रहा है, फिर आपके सशर्त स्टेटमेंट का ग्लोबल स्टेट चेंज के रूप में सही तरीके से पुनर्मूल्यांकन किया जाना चाहिए।
मैथ्यू राइडआउट

डार्ट /
स्पटर

72

डार्ट में, if/elseऔर switchकथन नहीं भाव हैं। वे एक मान नहीं लौटाते हैं ताकि आप उन्हें कंस्ट्रक्टर परमेस को पास न कर सकें। यदि आपके पास अपनी निर्माण पद्धति में बहुत अधिक सशर्त तर्क हैं, तो इसे आज़माना और सरल बनाना एक अच्छा अभ्यास है। उदाहरण के लिए, आप स्व-निहित तर्क को विधियों में स्थानांतरित कर सकते हैं, और 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);
}

1
यह सही उत्तर होना चाहिए! इस स्पष्टीकरण के लिए धन्यवाद, इसने मेरी मदद की!
स्लैमिट

34

रिकॉर्ड के लिए, डार्ट २.३ ने संग्रह शाब्दिक में / और कथन का उपयोग करने की क्षमता को जोड़ा। यह अब निम्नलिखित तरीके से किया जाता है:

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

स्पंदन समस्या # 28181 - सूची में इनलाइन सशर्त प्रतिपादन


मेरे पास 2.5 डार्ट हैं लेकिन मुझे कोड के ऊपर चलने में त्रुटि होती है। यह कहता है कि यह कोड पहले के संस्करणों के साथ संगत होना आवश्यक है। SDK बाधाओं को अपडेट करने की कोशिश करें
Aseem

एमम, दिलचस्प ~
होजेन

क्या वे लूप सुविधा के लिए जोड़ते हैं? यदि ऐसा है तो इसे कैसे लागू किया जाए?
प्रिंसबिलीजीके


एक भी विजेट की तरह साथ काम नहीं करता AppBar -> leading:याchild:
एलेक्स वांग

33

ऐसे मामले में मैं टर्नरी ऑपरेटर का उपयोग करने की सिफारिश करूंगा:

child: condition ? Container() : Center()

और फॉर्म के कोड से बचने की कोशिश करें:

if (condition) return A else return B

जो टर्नरी ऑपरेटर की तुलना में अनावश्यक रूप से अधिक क्रिया है।

लेकिन अगर अधिक तर्क की आवश्यकता है तो आप भी हो सकते हैं:

बिल्डर विजेट का उपयोग करें

बिल्डर विजेट जब एक बच्चे विजेट के लिए आवश्यक है एक बंद करने के इस्तेमाल की अनुमति के लिए है:

एक प्लेटोनिक विजेट जो अपने बच्चे के विजेट को प्राप्त करने के लिए एक बंद कॉल करता है।

विजेट बनाने के लिए आपको तर्क की आवश्यकता होती है कभी भी यह सुविधाजनक है , यह एक समर्पित फ़ंक्शन बनाने की आवश्यकता से बचा जाता है।

आप बच्चे के रूप में बिल्डर विजेट का उपयोग करते हैं, आप इसकी builderविधि में अपना तर्क प्रदान करते हैं :

Center(
  child: Builder(
    builder: (context) {
      // any logic needed...
      final condition = _whateverLogicNeeded();
      
      return condition
          ? Container();
          : Center();
    }
  )
)

बिल्डर रचनात्मक तर्क रखने के लिए एक सुविधाजनक स्थान प्रदान करता है। यह एट्रीऑन द्वारा प्रस्तावित तत्काल अनाम फ़ंक्शन की तुलना में अधिक सीधा है।

इसके अलावा, मैं मानता हूं कि तर्क को UI कोड से निकाला जाना चाहिए, लेकिन जब यह वास्तव में UI तर्क होता है तो इसे रखने के लिए कभी-कभी अधिक सुपाठ्य होता है।


यह मेरे लिए बहुत अच्छी तरह से दराज के आइटम पर क्लिक करने और शरीर को अद्यतन करने के लिए काम करता है
त्वरित शिक्षार्थी

22

मुझे पता चला कि Flutter UI बनाने के लिए सशर्त तर्क का उपयोग करने का एक आसान तरीका तर्क को UI के बाहर रखना है। यहाँ दो अलग-अलग रंगों को लौटाने के लिए एक समारोह है:

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

बहुत साफ-सुथरा क्योंकि आप कई विजेट में अपने रंग चयनकर्ता फ़ंक्शन का पुन: उपयोग कर सकते हैं।


1
मैंने यह कोशिश की और मेरे लिए सटीक तरीके से काम किया। धन्यवाद
अजय कुमार

18

मैं व्यक्तिगत रूप से इस तरह के ब्लॉक स्टेटमेंट वाले बच्चों में / अन्यथा बयान का उपयोग करता हूं। यह केवल डार्ट संस्करण 2.3.0 से ऊपर का समर्थन करता है।

यदि नहीं तो

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

यदि / और यदि

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

17

आप बस एक सशर्त विवरण का उपयोग कर सकते हैं a==b?c:d

उदाहरण के लिए :

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

मुझे उम्मीद है कि आपको विचार मिला होगा।

मान लीजिए कि कोई और शर्त नहीं है तो आप SizedBox.shrink () का उपयोग कर सकते हैं

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

यदि यह एक कॉलम है तो ?:ऑपरेटर को लिखने की आवश्यकता नहीं है

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

1
अगर कोई और शर्त नहीं है तो क्या होगा? कॉलम में, एक == b? C: null काम नहीं करेगा
cwhisperer

1
आप बस दूसरे विजेट के रूप में SizedBox.shrick () का उपयोग कर सकते हैं। जवाब अपडेट कर रहा है।
अफिनास ईएम

1
यदि यह एक स्तंभ है तो आप बिना किसी अन्य स्थिति के सीधे स्थिति का उपयोग कर सकते हैं: `अगर ('शर्त') विजेट () '
अफिनास ईएम

10

यहाँ समाधान है। मैंने इसे ठीक कर लिया है। यहाँ कोड है

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

इसका उपयोग कैसे करें
ardi

6

यदि आप विगेट्स की सूची का उपयोग करते हैं तो आप इसका उपयोग कर सकते हैं:

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

स्थिति? पाठ ("ट्रू"): अशक्त, यह कंसोल में एक त्रुटि को झूठा साबित करता है, रनटाइम निष्पादन पर
16 अप्रैल को

@exequielc आपको जोड़ना होगा .where (notNull) .toList () और WidgetList का अंत और विधि bool notNull (ऑब्जेक्ट o) => o = = null; पूरे उदाहरण की कोशिश करें ...
टोबीस

1
डार्ट 2.3 के अनुसार सशर्त रूप से एक सूची में एक विजेट शामिल करें जिसका आप उपयोग कर सकते हैं: [पाठ ("हैलो"), अगर (दुनिया) पाठ ("विश्व")]
ब्रेट सुटन

4

एक और विकल्प: ' 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];
  }
}

3

उपयोग करने के महीनों के बाद लोल ;: मुझे अभी पता चला है कि मैं इसका उपयोग कर सकता हूं:

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

2

यह शानदार लेख और बातचीत है। मैंने वर्णित के रूप में टर्नरी ऑपरेटर का उपयोग करने की कोशिश की। लेकिन कोड काम नहीं किया जिसके परिणामस्वरूप त्रुटि हुई।

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

मिसाल के तौर पर ऊपर का तीखा उदाहरण अग्रणी है। डार्ट एक त्रुटि के साथ जवाब देगा कि विजेट के बजाय एक अशक्त वापस आ गया था। आप अशक्त नहीं लौट सकते। विजेट वापस करने का सही तरीका होगा:

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

काम करने के लिए टर्नरी के लिए आपको एक विजेट वापस करने की आवश्यकता है। यदि आप कुछ भी वापस नहीं करना चाहते हैं तो आप एक खाली कंटेनर वापस कर सकते हैं।

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

सौभाग्य।


2

एक बटन के साथ

bool _paused = false;

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

1

**** आप इस विधि का उपयोग करके भी शर्तों का उपयोग कर सकते हैं ** **

 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

स्पंदन में यदि आप सशर्त प्रतिपादन करना चाहते हैं, तो आप ऐसा कर सकते हैं:

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

लेकिन क्या होगा अगर आप तृतीयक (यदि-और) स्थिति का उपयोग करना चाहते हैं? जब बच्चा विजेट बहुस्तरीय है।

आप इसके समाधान के लिए इसका उपयोग कर सकते हैं flutter_conditional_rendering एक स्पंदन पैकेज जो सशर्त रेंडरिंग को बढ़ाता है, if-else और स्विच स्थितियों का समर्थन करता है।

यदि-क्ष स्थिति:

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

स्विच स्थिति:

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>)एकल के बजाय विगेट्स की सूची प्रस्तुत करना चाहते हैं । का उपयोग करें Conditional.list()औरConditionalSwitch.list()!


1

अपने ऐप में मैंने एक WidgetChooserविजेट बनाया ताकि मैं सशर्त तर्क के बिना विजेट के बीच चयन कर सकूं:

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

यह WidgetChooserविजेट के लिए स्रोत है :

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

बहुत उपयोगी, साझा करने के लिए धन्यवाद!
पेट्रो

1

आप डार्ट में सशर्त बयानों के लिए टर्नरी ऑपरेटर का उपयोग कर सकते हैं, यह सरल है

(condition) ? statement1 : statement2

यदि conditionसत्य है तो statement1वसीयत को अन्यथा निष्पादित किया जाएगा statement2

एक व्यावहारिक उदाहरण लेते हुए

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

याद रखें कि क्या आप उपयोग करने जा रहे हैं nullक्योंकि Widget2इसका उपयोग करना बेहतर है SizedBox.shrink()क्योंकि कुछ माता-पिता विगेट्स एक nullबच्चे को प्राप्त करने के बाद अपवाद फेंक देंगे ।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.