مقدمة
استخدام عنصر Radio في تطبيقات Flutter
في هذا الدرس، سنتعلم كيفية استخدام عنصر Radio في تطبيقات Flutter. عنصر Radio يُستخدم للسماح للمستخدم بتحديد خيار واحد من بين مجموعة من الخيارات المتاحة. سنقوم بفهم كيفية تطبيق واستخدام عنصر Radio بشكل صحيح، بالإضافة إلى تعلم كيفية تنظيم وتحسين واجهة المستخدم باستخدامه.
في نهاية هذا الدرس، سنكون قادرين على:
فهم مفهوم واستخدام عنصر Radio في تطبيقات Flutter.
تطبيق عنصر Radio لعرض خيارات متعددة للمستخدم.
استخدام عنصر RadioListTile لتنظيم واجهة المستخدم بشكل منظم.
تحسين تجربة المستخدم باستخدام ميزات إضافية مثل العداد الزمني وإعادة التحميل التلقائي.
هيا نبدأ بالتعرف على كيفية استخدام عنصر Radio لجعل تطبيقاتنا في Flutter أكثر تفاعلية وجاذبية للمستخدمين.
في Flutter، يمكنك استخدام حزمة radio لإنشاء عناصر Radio و RadioListTile. هذه المكونات تسمح للمستخدمين بتحديد خيار واحد من بين عدة خيارات.
تبدأ عملية إنشاء عنصر Radio بتعريف متغير يحتوي على قيمة الخيار، ثم استخدام مكون Radio مع قيمة محددة لـ value و groupValue. ويجب أن يكون هناك تابع يُشغل عندما يقوم المستخدم بتغيير القيمة المحددة. يمكنك تنفيذ ذلك باستخدام وظيفة setState() لتحديث الحالة.
على سبيل المثال، يمكنك القيام بشيء مشابه لهذا:
تطبيق 1
import 'package:flutter/material.dart'; class RadioWidget extends StatefulWidget { @override _RadioWidgetState createState() => _RadioWidgetState(); } class _RadioWidgetState extends State<RadioWidget> { String? selectedOption; // Making selectedOption nullable @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Radio Example'), ), body: Column( children: <Widget>[ RadioListTile( title: Text('Option 1'), value: 'Option 1', groupValue: selectedOption, onChanged: (String? value) { // Specifying value as String? setState(() { selectedOption = value; // No need to cast value here }); }, ), RadioListTile( title: Text('Option 2'), value: 'Option 2', groupValue: selectedOption, onChanged: (String? value) { // Specifying value as String? setState(() { selectedOption = value; // No need to cast value here }); }, ), RadioListTile( title: Text('Option 3'), value: 'Option 3', groupValue: selectedOption, onChanged: (String? value) { // Specifying value as String? setState(() { selectedOption = value; // No need to cast value here }); }, ), ], ), ); } } void main() { runApp(MaterialApp( home: RadioWidget(), )); }
في هذا المثال، قمنا إنشاء واجهة مستخدم بسيطة تحتوي على ثلاثة RadioListTiles، يمكن للمستخدم اختيار واحد منها. عند اختيار المستخدم خيارًا معينًا، يتم تحديث الحالة باستخدام() setStateويتم تغيير selectedOption إلى القيمة المحددة.
شرح الكود في اسطر منفصلة معنونة منظمة
سنشرح الكود خطوة بخطوة بشكل منظم:
استيراد الحزم وتعريف الفئة الرئيسية:
import 'package:flutter/material.dart'; class RadioWidget extends StatefulWidget { @override _RadioWidgetState createState() => _RadioWidgetState(); }
تم استيراد حزمة المكونات المادية (Material) من Flutter وتعريف فئة رئيسية تستخدم StatefulWidget.
تعريف الحالة والبنية الأساسية للواجهة:
class _RadioWidgetState extends State<RadioWidget> { String selectedOption = ''; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Radio Example'), ), body: Column( children: <Widget>[ // RadioListTiles هنا ], ), ); } }
يتم تعريف _RadioWidgetState كفئة تحتوي على حالة selectedOption لتتبع الخيار المحدد. في داخل ()build يتم بناء واجهة المستخدم باستخدام Scaffold وتضمين AppBar وColumn لتنظيم العناصر.
إنشاء RadioListTiles:
RadioListTile( title: Text('Option 1'), value: 'Option 1', groupValue: selectedOption, onChanged: (value) { setState(() { selectedOption = value; }); }, ),
تم استخدام RadioListTile لعرض الخيارات. تم تحديد عنوان الخيار باستخدام title وتحديد قيمة الخيار بواسطة value. يتم تحديد groupValue بقيمة selectedOption للسماح بتحديد خيار واحد في كل مرة. وعند تغيير القيمة المحددة، يتم تشغيل onChanged حيث يتم تحديث الحالة بواسطة ()setState.
تشغيل التطبيق:
void main() { runApp(MaterialApp( home: RadioWidget(), )); }
تم تشغيل التطبيق باستخدام ()runApp وتم تمرير ()RadioWidget كـ home لإظهار الواجهة الرئيسية.
شجرة العناصر لهذا التطبيق
- MaterialApp - Scaffold - AppBar - Text ('Radio Example') - Column - RadioListTile (Option 1) - RadioListTile (Option 2) - RadioListTile (Option 3)
MaterialApp: يعرض التطبيق الذي يحتوي على مكونات المواد من Flutter.
Scaffold: توفر هيكلًا للتطبيق، بما في ذلك AppBar و body.
AppBar: الشريط العلوي للتطبيق يحتوي على عنوان الصفحة.
Text: يعرض نص عنوان الصفحة.
Column: تنظيم عمودي لعناصر الواجهة.
RadioListTile: عناصر الراديو التي يمكن للمستخدم اختيار واحدة من بينها، في هذه الحالة تم تكرارها ثلاث مرات لثلاثة خيارات مختلفة.
في Flutter، مكون Radio يستخدم لإنشاء عنصر واجهة مستخدم يتيح للمستخدم اختيار خيار من بين عدة خيارات. هنا هي الخصائص والمكونات والوظائف الرئيسية لمكون Radio:
Radio: هو المكون الرئيسي لعرض خيارات الراديو. يتضمن خصائص رئيسية مثل:
value: القيمة المرتبطة بالخيار.
groupValue: القيمة المحددة في مجموعة الراديو.
onChanged: دالة تُشغَّل عندما يتغير حالة الراديو.
RadioListTile: هو مكون ثانوي يجمع بين عنصر Radio وعنصر ListTile، مما يتيح عرض خيار الراديو بالإضافة إلى عنوان وملصق. بعض الخصائص الهامة:
title: عنوان يعرض بجانب الراديو.
subtitle: نص إضافي يمكن إضافته لتوضيح الخيار.
value: القيمة المرتبطة بالخيار.
groupValue: القيمة المحددة في مجموعة الراديو.
onChanged: دالة تُشغَّل عندما يتغير حالة الراديو.
groupValue: قيمة المجموعة للراديوات. يجب أن يكون هذا القيمة متطابقة مع value للراديو المحدد.
value: القيمة المرتبطة بالراديو. عندما يتم اختيار الراديو، يتم تعيين groupValue إلى هذه القيمة.
onChanged: دالة تُشغَّل عندما يتغير حالة الراديو. يتم تمرير قيمة الراديو الجديدة كمعامل لهذه الدالة.
باستخدام هذه المكونات والخصائص، يمكنك بسهولة إنشاء واجهة مستخدم تتيح للمستخدم اختيار خيار واحد من بين عدة خيارات.
بالطبع، إليك كيفية استخدام مكون Radio خطوة بخطوة في Flutter:
استيراد الحزمة المطلوبة:
قبل استخدام مكونات Flutter، يجب عليك استيراد الحزمة المناسبة. في حالة Radio، يمكنك استيراد حزمة المكونات المادية (material) كما يلي:
import 'package:flutter/material.dart';
تعريف الحالة:
قبل بناء الواجهة، يجب تعريف الحالة التي تتحكم في قيمة الراديو المختارة. يمكنك استخدام StatefulWidget لهذا الغرض. على سبيل المثال:
class RadioExample extends StatefulWidget { @override _RadioExampleState createState() => _RadioExampleState(); }
تعريف حالة الراديو:
في حالة الراديو، يتم استخدام قيمة محددة لتمثيل الخيار المحدد. قد يتم تخزين هذه القيمة في حالة الفئة. على سبيل المثال:
class _RadioExampleState extends State<RadioExample> { String selectedOption = ''; }
بناء الواجهة:
يجب بناء الواجهة داخل وظيفة build() في _RadioExampleState. يمكنك استخدام مكونات RadioListTile لعرض الراديوات. على سبيل المثال:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Radio Example'), ), body: Column( children: <Widget>[ RadioListTile( title: Text('Option 1'), value: 'Option 1', groupValue: selectedOption, onChanged: (value) { setState(() { selectedOption = value; }); }, ), RadioListTile( title: Text('Option 2'), value: 'Option 2', groupValue: selectedOption, onChanged: (value) { setState(() { selectedOption = value; }); }, ), RadioListTile( title: Text('Option 3'), value: 'Option 3', groupValue: selectedOption, onChanged: (value) { setState(() { selectedOption = value; }); }, ), ], ), ); }
تشغيل التطبيق:
أخيرًا، يجب تشغيل التطبيق باستخدام runApp() وتمرير عنصر RadioExample() كعنصر أساسي. على سبيل المثال:
void main() { runApp(MaterialApp( home: RadioExample(), )); }
بهذه الطريقة، يمكنك استخدام مكون Radio في Flutter لإنشاء واجهة مستخدم تتيح للمستخدم اختيار خيار واحد من بين عدة خيارات.
شجرة عناصر التطبيق:
تفضل هذه هي شجرة عناصر التطبيق بعد تطبيق الكود السابق:
- MaterialApp - Scaffold - AppBar - Text ('Radio Example') - Column - RadioListTile (Option 1) - RadioListTile (Option 2) - RadioListTile (Option 3)
MaterialApp: عنصر رئيسي يشمل التطبيق بأكمله والذي يحتوي على المواد المصممة.
Scaffold: هيكل التطبيق يحتوي على AppBar والـ Body.
AppBar: الشريط العلوي للتطبيق يحتوي على عنوان الصفحة.
Text: يعرض نص العنوان.
Column: يسمح بتنظيم العناصر بشكل عمودي.
RadioListTile (Option 1): يظهر الخيار الأول للراديو.
RadioListTile (Option 2): يظهر الخيار الثاني للراديو.
RadioListTile (Option 3): يظهر الخيار الثالث للراديو.
هذه الشجرة تمثل ترتيب العناصر داخل التطبيق، حيث يتم تضمين كل عنصر داخل العنصر السابق بهذا الترتيب.
تطبيق 2 عن اسخدام Radio خطوة بخطوة
طبقاً لذلك، سأقوم بإنشاء تطبيق بسيط يستخدم Radio في Flutter. سيكون التطبيق يحتوي على ثلاثة خيارات وسيعرض الخيار المحدد للمستخدم.
نقم بإنشاء ملف main.dart وقم بإضافة الكود التالي:
import 'package:flutter/material.dart'; void main() { runApp(RadioApp()); } class RadioApp extends StatefulWidget { @override _RadioAppState createState() => _RadioAppState(); } class _RadioAppState extends State<RadioApp> { String selectedOption = 'Option 1'; void handleOptionChange(String? value) { setState(() { selectedOption = value!; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Radio Example'), ), body: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ RadioListTile( title: Text('Option 1'), value: 'Option 1', groupValue: selectedOption, onChanged: handleOptionChange, ), RadioListTile( title: Text('Option 2'), value: 'Option 2', groupValue: selectedOption, onChanged: handleOptionChange, ), RadioListTile( title: Text('Option 3'), value: 'Option 3', groupValue: selectedOption, onChanged: handleOptionChange, ), const SizedBox(height: 20), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( 'Selected Option: $selectedOption', style: TextStyle(fontSize: 18), ), ), ], ), ), ); } }
هذا التطبيق يقوم بعرض ثلاثة خيارات باستخدام RadioListTile. عندما يقوم المستخدم بتحديد أحد الخيارات، يتم تحديث القيمة المختارة وعرضها أسفل الخيارات.
نقم بتشغيل التطبيق باستخدام flutter run من داخل مجلد مشروع Flutter الخاص بنا، وسيتم تشغيل التطبيق على محاكي الهاتف أو الجهاز الذي نقوم بتشغيله.
شجرة العناصر
شجرة العناصر لتطبيق استخدام Radio:
- MaterialApp - Scaffold - AppBar - Text ('Radio Example') - Column - RadioListTile (Option 1) - RadioListTile (Option 2) - RadioListTile (Option 3) - SizedBox - Padding - Text ('Selected Option: $selectedOption')
MaterialApp: تمثل التطبيق بأكمله.
Scaffold: هيكل التطبيق يحتوي على AppBar وBody.
AppBar: الشريط العلوي للتطبيق يحتوي على عنوان الصفحة.
Text: يعرض نص العنوان.
Column: يتم استخدامه لتنظيم العناصر بشكل عمودي.
RadioListTile (Option 1): عنصر RadioListTile الذي يمثل الخيار الأول.
RadioListTile (Option 2): عنصر RadioListTile الذي يمثل الخيار الثاني.
RadioListTile (Option 3): عنصر RadioListTile الذي يمثل الخيار الثالث.
SizedBox: تستخدم لإضافة مساحة بين RadioListTile والنص.
Padding: تستخدم لإضافة حواف للنص.
Text: يعرض النص “Selected Option: $selectedOption” الذي يظهر الخيار المحدد.
بالطبع، سأقوم بتصميم كويز بسيط يستخدم Radio وخصائصه في Flutter. سيكون الهدف هو عرض سؤال متعدد الخيارات مع السماح للمستخدم بتحديد إجابة واحدة.
هنا الخطوات:
تصميم الشاشة:
سنقوم بتصميم واجهة مستخدم بسيطة تعرض السؤال والخيارات وزر لتأكيد الاختيار.
تحضير بيانات الكويز:
سنستخدم قائمة من الأسئلة مع الخيارات والإجابة الصحيحة.
تنفيذ الواجهة والمنطق:
سنقوم بتنفيذ الواجهة وربطها ببيانات الكويز.
بدايةً، دعنا نقوم بتصميم واجهة المستخدم. لهذا الغرض، سنستخدم كلاس StatefulWidget للتحكم في حالة الصفحة. سيتم تخزين السؤال الحالي والخيارات والإجابة الصحيحة في حالة الصفحة.
هنا الكود:
import 'package:flutter/material.dart'; void main() { runApp(QuizApp()); } class QuizApp extends StatefulWidget { @override _QuizAppState createState() => _QuizAppState(); } class _QuizAppState extends State<QuizApp> { int _currentQuestionIndex = 0; List<Map<String, dynamic>> _questions = [ { 'question': 'What is the capital of France?', 'options': ['Paris', 'London', 'Rome', 'Berlin'], 'answer': 'Paris', }, { 'question': 'What is 2 + 2?', 'options': ['3', '4', '5', '6'], 'answer': '4', }, // Add more questions here ]; String _selectedAnswer = ''; bool _isAnswered = false; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Quiz App'), ), body: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( _questions[_currentQuestionIndex]['question'], style: TextStyle(fontSize: 18), ), SizedBox(height: 20), ...(_questions[_currentQuestionIndex]['options'] as List<String>) .map((option) { return RadioListTile( title: Text(option), value: option, groupValue: _selectedAnswer, onChanged: _isAnswered ? null : (value) { setState(() { _selectedAnswer = value.toString(); }); }, ); }).toList(), SizedBox(height: 20), ElevatedButton( onPressed: _isAnswered ? null : _submitAnswer, child: Text('Submit'), ), ], ), ), ), ); } void _submitAnswer() { setState(() { _isAnswered = true; if (_selectedAnswer == _questions[_currentQuestionIndex]['answer']) { // Show correct answer feedback showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Correct!'), content: Text('You got it right.'), actions: [ TextButton( onPressed: () { Navigator.pop(context); _goToNextQuestion(); }, child: Text('Next'), ), ], ); }, ); } else { // Show incorrect answer feedback showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Incorrect!'), content: Text('Try again.'), actions: [ TextButton( onPressed: () { Navigator.pop(context); }, child: Text('OK'), ), ], ); }, ); } }); } void _goToNextQuestion() { if (_currentQuestionIndex < _questions.length - 1) { setState(() { _currentQuestionIndex++; _selectedAnswer = ''; _isAnswered = false; }); } else { // Quiz is finished showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Congratulations!'), content: Text('You have completed the quiz.'), actions: [ TextButton( onPressed: () { Navigator.pop(context); setState(() { _currentQuestionIndex = 0; _selectedAnswer = ''; _isAnswered = false; }); }, child: Text('Restart Quiz'), ), ], ); }, ); } } }
دعونا نشرح الكود:
يتم استيراد المكتبات اللازمة وتعريف الكلاس QuizApp كـ StatefulWidget.
تم تعريف حالة _currentQuestionIndex لتتبع السؤال الحالي، وقائمة _questions لتخزين الأسئلة والخيارات والإجابات الصحيحة.
في واجهة المستخدم، نقوم بعرض السؤال الحالي وخياراته باستخدام Text و RadioListTile.
تم تعيين قيمة المجموعة والقيمة المحددة للراديو على أساس الإجابة المختارة.
يتم تعطيل تغيير الإجابة بمجرد الإجابة الصحيحة.
عند الضغط على زر “Submit”، يتم التحقق من الإجابة وإظهار رسالة تعليمات بناءً على صحة الإجابة.
بعد ذلك، يمكن للمستخدم الانتقال إلى السؤال التالي بالضغط على زر “Next”.
يتم عرض رسالة التهنئة عندما يكمل المستخدم الكويز ويعرض زرًا لإعادة بدء الكويز.
شجرة العناصر
هاكم شجرة العناصر لتطبيق الكويز باستخدام Radio:
- MaterialApp - Scaffold - AppBar - Text ('Quiz App') - Padding - Column - Text (Question) - SizedBox - RadioListTile (Option 1) - RadioListTile (Option 2) - RadioListTile (Option 3) - SizedBox - ElevatedButton ('Submit')
MaterialApp: تمثل التطبيق بأكمله.
Scaffold: هيكل التطبيق يحتوي على AppBar وBody.
AppBar: الشريط العلوي للتطبيق يحتوي على عنوان الصفحة.
Text: يعرض نص العنوان.
Padding: يستخدم لإضافة هامش حول العناصر.
Column: يستخدم لتنظيم العناصر بشكل عمودي.
Text (Question): يعرض نص السؤال الحالي.
SizedBox: يستخدم لإضافة مساحة بين العناصر.
RadioListTile (Option 1): يعرض الخيار الأول للراديو.
RadioListTile (Option 2): يعرض الخيار الثاني للراديو.
RadioListTile (Option 3): يعرض الخيار الثالث للراديو.
ElevatedButton (‘Submit’): زر لتأكيد الإجابة.
هاكم اختبارا بسيطا حول استخدام عنصر الـ Radio في تطبيقات Flutter:
خيار لاختيار قيمة من بين عدة خيارات متاحة.
عنصر لعرض الصور.
عنصر لعرض قائمة منسدلة.
يتميز بدائرة ملونة يمكن تحديدها.
يتميز بصورة على شكل دائرة.
لا يمكن تمييزه عن العناصر الأخرى.
RadioListTile.
RadioButton.
RadioGroup.
باستخدام عنصر الـ RadioGroup.
بتغيير مظهر عناصر الـ Radio.
يمكن اختيار أكثر من خيار واحد.
عرض قائمة منسدلة من عناصر الـ Radio.
عرض عناصر الـ Radio بشكل قائمة.
عرض عناصر الـ Radio بشكل لائحة.
باستخدام خاصية isMultiSelect الموجودة في عنصر الـ Radio.
بتعريف قائمة من عناصر الـ Radio.
لا يمكن استخدام عنصر الـ Radio لعرض خيارات متعددة.
value.
selectedValue.
checked.
يسمح عنصر الـ Radio بتحديد خيار واحد فقط بينما يسمح Checkbox بتحديد عدة خيارات.
لا يوجد فرق بينهما.
يستخدم كل منهما للتبديل بين حالتين.
لتحديث الواجهة بعد تغيير حالة المتغيرات.
لتحديد القيمة المختارة في عنصر الـ Radio.
لعرض رسائل توجيهية للمستخدم.
تجميع عناصر الـ Radio في مجموعات لتمكين اختيار واحد فقط من بينها.
تجميع عناصر الـ Radio في مجموعات لتمكين اختيار عدة خيارات.
استخدامه لتنظيم عناصر الواجهة بشكل منظم.
الاجابات
ما هو عنصر الـ Radio في Flutter؟
الإجابة الصحيحة: خيار لاختيار قيمة من بين عدة خيارات متاحة.
كيف يتم تمييز عنصر الـ Radio عن العناصر الأخرى في Flutter؟
الإجابة الصحيحة: يتميز بدائرة ملونة يمكن تحديدها.
ما العنصر الذي يتم استخدامه لعرض قائمة من خيارات الـ Radio في Flutter؟
الإجابة الصحيحة: RadioListTile.
كيف يمكن تجنب اختيار أكثر من خيار واحد باستخدام عناصر الـ Radio في Flutter؟
الإجابة الصحيحة: باستخدام عنصر RadioGroup.
ما هي وظيفة عنصر RadioListTile في Flutter؟
الإجابة الصحيحة: عرض قائمة منسدلة من عناصر الـ Radio.
كيف يمكن استخدام عنصر الـ Radio في Flutter لعرض خيارات متعددة؟
الإجابة الصحيحة: بتعريف قائمة من عناصر الـ Radio.
ما هو الخاصية المستخدمة لتحديد القيمة المختارة في عنصر الـ Radio في Flutter؟
الإجابة الصحيحة: value.
ما هو الفرق بين عنصر الـ Radio وعنصر Checkbox في Flutter؟
الإجابة الصحيحة: يسمح عنصر الـ Radio بتحديد خيار واحد فقط بينما يسمح Checkbox بتحديد عدة خيارات.
ما هو استخدام الدالة setState في Flutter؟
الإجابة الصحيحة: لتحديث الواجهة بعد تغيير حالة المتغيرات.
ما هو الهدف من استخدام عنصر RadioGroup في Flutter؟
الإجابة الصحيحة: تجميع عناصر الـ Radio في مجموعات لتمكين اختيار واحد فقط من بينها