Theory
Form दो तरह के सवाल पूछता है
FestConnect Flutter के registration form का choices section आ गया है:
एक carry bag add करें? Event updates लें?: independent yes/nos: कोई भी tick कीजिए, दोनों tick कीजिए।
Payment: Cash, Card या UPI?: exactly एक।
आप इस split से दो बार मिले हैं: BCA404 का CheckBox-vs-RadioButton और Unit 1 के Android widgets। Flutter split रखता है, पिछले lesson की controlled-widget law रखता है: और चुपचाप relocate करता है radio EXCLUSIVITY कहाँ से आती है, एक तरीके से जो हर Android और VB veteran को पकड़ता है।
Theory
Checkbox: एक-एक Bool, हमेशा Independent
हर checkbox एक controlled widget है जो अपने own bool के around wrapped है:
bool carryBag = false;
Checkbox(
value: carryBag,
onChanged: (v) => setState(() { carryBag = v!; }),
)
Slider का loop verbatim: value state display करता है, onChanged flip publish करता है। दो checkboxes = 2 bools = total independence: जो exactly any-of semantics है। Labelled convenience form है CheckboxListTile (checkbox + title एक tappable row में)।
Practical
दोनों Question Kinds, एक Form
class _RegisterState extends State<RegisterScreen> {
bool carryBag = false; // checkbox: own bool each
bool wantsUpdates = true;
String payMode = 'upi'; // ONE variable = ONE radio group
@override
Widget build(BuildContext context) {
return Column(
children: [
CheckboxListTile(
title: const Text('Add a carry bag (Rs 10)'),
value: carryBag,
onChanged: (v) => setState(() { carryBag = v!; }),
),
CheckboxListTile(
title: const Text('Send me event updates'),
value: wantsUpdates,
onChanged: (v) => setState(() { wantsUpdates = v!; }),
),
RadioListTile<String>(
title: const Text('Cash'),
value: 'cash', // this radio's identity
groupValue: payMode, // the SHARED group variable
onChanged: (v) => setState(() { payMode = v!; }),
),
RadioListTile<String>(
title: const Text('Card'),
value: 'card',
groupValue: payMode,
onChanged: (v) => setState(() { payMode = v!; }),
),
RadioListTile<String>(
title: const Text('UPI'),
value: 'upi', // equals payMode: renders selected
groupValue: payMode,
onChanged: (v) => setState(() { payMode = v!; }),
),
],
);
}
}
Theory
Radio: Shared Variable से Exclusivity
Radio trio की machinery पढ़िए:
- हर Radio एक value carry करता है: इसकी identity ('cash', 'card', 'upi')
- सभी 3 अपने groupValue को SAME state variable, payMode पर point करते हैं
- जिस radio का
value == groupValueवह selected render होता है: payMode = 'upi' के साथ, UPI row dot दिखाती है - Card tap करना setState(payMode = 'card') चलाता है: ONE assignment, और rebuild नए groupValue के against सभी 3 radios repaint करता है: Card dot पाता है, UPI इसे खोता है
कहीं कोई RadioGroup नहीं, कोई GroupBox नहीं, कोई container नहीं: group IS shared variable।
Quiz
Flutter में, 3 Radio widgets को एक exclusive group की तरह behave क्या कराता है?
- उन्हें same Column या container के अंदर रखना
- सभी 3 का same groupValue state variable share करना
- उन्हें same value parameter देना
- उन्हें एक RadioGroup widget में wrap करना, Android की तरह
Show the answer
सभी 3 का same groupValue state variable share करना
Group STATE में रहता है, layout में नहीं: एक payMode variable पढ़ने वाले 3 radios एक group हैं चाहे वे screen पर कहीं भी बैठें: अलग-अलग Rows में scattered भी। Option A वह reflex है जिसे यह question hunt करता है: BCA404 का GroupBox और Android का RadioGroup groups को CONTAINER से define करते थे, और Flutter deliberately ऐसा नहीं करता। Option C 3 radios को same IDENTITY देगा: वे सब एक साथ select होंगे, exclusive का opposite। Option D एक widget import करता है जो Flutter ship नहीं करता। Exam sentence: exclusivity shared groupValue follow करती है; selection value == groupValue है।
Think first
दो Questions, तो कितने Variables?
Form में एक दूसरा radio question बढ़ता है: Delivery: Take away / Home delivery। BCA404 में इसे एक दूसरा GroupBox चाहिए था। Flutter में इसे क्या चाहिए, और अगर आप lazily दोनों questions के लिए payMode reuse करें तो क्या ग़लत होता है? Trace कीजिए, फिर tap कीजिए।
Show the answer
एक second state variable: String delivery = 'takeaway'; और नए 2 radios groupValue को उस पर point करते हैं। दोनों के लिए payMode reuse कीजिए और सभी 5 radios ONE accidental group बनाते हैं: Home delivery चुनना (payMode = 'home') UPI deselect करता है, और आपका payment चुपचाप 'home' बन जाता है: बिल्कुल वही merged-group bug जो BCA404 के radios का एक bare form पर था, layout से state में relocated। अपने notes में लिखने वाला mapping: एक QUESTION = एक groupValue variable, exactly जैसे old worlds में एक question = एक container था।
Watch out
Choice-Widget Slips
onChanged: null उन्हें Freeze करता है: buttons की तरह, एक null handler control को disabled render करता है: deliberately useful, accidentally baffling।
v! Bang: onChanged एक nullable (bool? / T?) hand करता है; v! store करने से पहले non-null assert करता है: modern Dart की null safety अपने teeth दिखाते हुए।
One-of Questions के लिए Checkbox: दोनों payment checkboxes ticked होना एक data bug है जो form design में born हुआ: BCA404 rule (any-of = check, one-of = radio) सभी 3 platforms में survive करता है।
Theory
Controlled-Widget Law, दूसरा और तीसरा Witness
Checkbox और Radio ने अभी testify किया: state से value, onChanged + setState से change: और Radio ने insight add किया कि Flutter में GROUPING भी state है। यही framework का philosophical heart है: layout arrange करता है, state decide करता है, widgets सिर्फ़ display करते हैं। Unit 5 progress indicators और एक deeper Stack के साथ अगला खुलती है: loading overlay जो हर real booking flow को चाहिए।
Summary
Key takeaways
- Checkbox: value (अपना own bool) + onChanged + setState: independent any-of choices; labelled rows के लिए CheckboxListTile।
- Radio<T>: value radio की identity है; groupValue shared state variable पर point करता है; value == groupValue होने पर selected।
- Exclusivity SHARED groupValue से आती है: containers से नहीं (Android/VB.NET contrast)।
- एक question = एक groupValue variable; questions में एक reuse करना groups merge करता है।
- onChanged: null disable करता है; handlers nullables receive करते हैं (इसलिए v!)।
- Any-of = checkbox, one-of = radio: rule अपने तीसरे platform पर survive करता है।
- Memory hook: group एक variable है, एक box नहीं।