تنشئ الأداة SizedBox.shrinkمربعًا فارغًا بدون حجم. ويمكن استخدامها كعلامة نائبة غير مرئية عندما تحتاج إلى توفير أداة أو استبدال أداة.
تصميم عنصر واجهة المستخدم DropdownButton
يقدم DropdownButtonسمات إضافية يمكن استخدامها لتصميم القائمة المنسدلة.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> _languages = ['English', 'German', 'French'];
String _language = 'English';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.blueAccent,
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
borderRadius: BorderRadius.circular(10),
dropdownColor: Colors.blueAccent,
icon: const Icon(Icons.language),
iconEnabledColor: Colors.white,
iconSize: 30,
items: _languages
.map<DropdownMenuItem<String>>(
(String language) => DropdownMenuItem<String>(
value: language,
child: Text(language),
),
)
.toList(),
onChanged: (String? language) => setState(
() => _language = language ?? _language,
),
padding: const EdgeInsets.symmetric(horizontal: 30),
style: const TextStyle(fontSize: 20, color: Colors.white),
value: _language,
),
),
),
),
),
);
}
}
في مقتطف التعليمات البرمجية أعلاه، قمنا بتغيير ألوان كل من الزر والقائمة المنسدلة. لتغيير لون DropdownButton، قمنا بتغليفه بعنصر Inkواجهة مستخدم. يضمن هذا بقاء تأثير التموج مرئيًا، حيث سيؤدي استخدام عنصر واجهة مستخدم ColoredBoxأو Containerإلى إزالة هذا التأثير. يتم تعيين لون القائمة المنسدلة باستخدام dropdownColorالسمة.
داخل DropdownButtonعنصر واجهة المستخدم، قمنا بتغيير نصف قطر الحدود عن طريق تعيين borderRadiusالسمة إلى BorderRadius.circular(10). نفس القيمة التي استخدمناها داخل decorationسمة عنصر Inkواجهة المستخدم.
لقد أضفنا أيضًا أيقونة باستخدام السمات iconو iconEnabledColorو و iconSize. وأخيرًا، أضفنا حشوًا أفقيًا إلى الزر وقمنا بتغيير لون النص إلى الأبيض.
إذا كنت تريد معرفة طرق مختلفة للحفاظ على تأثير التموج، فراجع المقالة التالية: Flutter InkWell لا يظهر تأثير التموج
أداة DropdownButtonFormField
بدلاً من استخدام DropdownButtonالأداة، يمكننا أيضًا استخدام DropdownButtonFormFieldالأداة. على الرغم من أن هذه الأداة مخصصة للاستخدام داخل Formأداة، إلا أنه يمكن استخدامها أيضًا خارجها Form.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> _languages = ['English', 'German', 'French'];
String _language = 'English';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 200,
child: DropdownButtonFormField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
contentPadding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.blueAccent, width: 1.5),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.blueAccent, width: 2.5),
),
labelText: 'Language',
labelStyle: Theme.of(context).textTheme.titleMedium?.copyWith(fontSize: 18),
),
items: _languages
.map<DropdownMenuItem<String>>(
(String language) => DropdownMenuItem<String>(
value: language,
child: Text(language),
),
)
.toList(),
onChanged: (String? language) => setState(
() => _language = language ?? _language,
),
value: _language,
),
),
),
),
);
}
}
في مقتطف الكود أعلاه، استبدلنا DropdownButtonالأداة بالأداة DropdownButtonFormField. أحد الاختلافات الرئيسية هو أنها DropdownButtonFormFieldتتضمن decorationسمة توفر العديد من خيارات التصميم.
على سبيل المثال، أضفنا حدًا أزرق حول زر القائمة المنسدلة وأضفنا تسمية تعرض "اللغة". بشكل افتراضي، DropdownButtonFormFieldتشغل الأداة العرض الكامل، لذا قمنا بتغليفها داخل SizedBoxأداة لتعيين عرض ثابت يبلغ 200. وبخلاف ذلك، ما زلنا نستخدم نفس السمات كما في السابق لعرض العناصر وتحديث العنصر المحدد.
أداة PopupMenuButton في Flutter
بالإضافة إلى استخدام عناصر واجهة المستخدم DropdownButtonالرسومية DropdownButtonFormField، يمكننا أيضًا استخدام PopupMenuButtonعناصر واجهة المستخدم الرسومية. ورغم أنه من المفترض استخدامها مع الأيقونات وليس النصوص، إلا أنه لا يزال بإمكاننا استخدامها لعرض قوائم منسدلة مماثلة لما فعلناه في الأقسام السابقة.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> _languages = ['English', 'German', 'French'];
String _language = 'English';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: PopupMenuButton(
iconSize: 30,
icon: Text(_language),
initialValue: _language,
itemBuilder: (BuildContext context) => _languages
.map<PopupMenuItem<String>>(
(String language) => PopupMenuItem<String>(
value: language,
child: Text(language),
),
)
.toList(),
onSelected: (String? language) => setState(
() => _language = language ?? _language,
),
),
),
),
);
}
}
في مقتطف التعليمات البرمجية أعلاه، استبدلنا DropdownButtonبـ PopupMenuButtonwidget لعرض القوائم المنسدلة. PopupMenuButtonتحتوي على سمات مختلفة مقارنة بـ DropdownButton. لإضافة عناصر القائمة المنسدلة، نستخدم itemBuilderالسمة. تأخذ هذه السمة قائمة من PopupMenuEntryالحالات. نستخدم نفس نهج التعيين كما في السابق لإرجاع قائمة من PopupMenuItemعناصر widget، والتي يتم قبولها لأنها تمتد إلى PopupMenuEntryالفئة.
نستخدم iconالسمة لعرض اللغة المحددة حاليًا داخل الزر. وهذا ممكن لأن السمة iconتقبل أي عنصر واجهة مستخدم. ولتحديث اللغة إلى اللغة المحددة حديثًا، نستخدم السمتين initialValueو onSelected. وعلى الرغم من اختلاف الأسماء، فإن هذه السمات تعمل بشكل مشابه لسمات valueو onChangedللعنصر DropdownButtonواجهة المستخدم.
حزمة الزر المنسدل2
لمزيد من خيارات التخصيص، يمكننا استخدام DropdownButton2الحزمة. إحدى الفوائد الرئيسية لهذه الحزمة هي أنها تعرض القائمة المنسدلة مباشرةً أسفل الزر افتراضيًا. وهذا مفيد لأن الأدوات المضمنة غالبًا ما تعرض القائمة المنسدلة في مواضع مختلفة حسب العنصر المحدد، وهو ما قد لا يناسب احتياجاتك دائمًا.
تثبيت حزمة Dropdown Button2
لتثبيت حزمة Dropdow Button2 https://pub.dev/packages/dropdown_button2 ، قم بتنفيذ الأمر التالي داخل جذر مشروعك:
flutter pub add dropdown_button2
بمجرد تنفيذ الأمر، تأكد من فحص ملفك pubspec.yaml بحثًا عن التبعيات المضافة. يجب أن ترى حزمة Dropdown Button2 مضمنة في قسم التبعيات، مثل هذا:
dependencies:
dropdown_button2: ^2.3.9
تنفيذ حزمة Dropdown Button2
توفر حزمة Dropdown Button2 DropdownButton2أداة. ويتم تنفيذ الأداة بنفس طريقة تنفيذ الأداة المضمنة DropdownButton.
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> _languages = ['English', 'German', 'French'];
String _language = 'English';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: DropdownButton2(
items: _languages
.map<DropdownMenuItem<String>>(
(String language) => DropdownMenuItem<String>(
value: language,
child: Text(language),
),
)
.toList(),
onChanged: (String? language) => setState(
() => _language = language ?? _language,
),
value: _language,
),
),
),
);
}
}
في مقتطف التعليمات البرمجية أعلاه، نستخدم الآن DropdownButton2الأداة لعرض قائمة منسدلة. وكما ترى، لا يزال بإمكاننا استخدام نفس السمات كما في السابق. ومع ذلك، كما هو موضح في ملف GIF ، سترى أن القائمة المنسدلة تظهر دائمًا أسفل الزر.
تصميم عنصر واجهة المستخدم DropdownButton2
على غرار DropdownButtonالأداة، DropdownButton2تسمح الأداة بالتصميم من خلال سماتها. ومع ذلك، DropdownButton2توفر الأداة المزيد من خيارات التصميم وعادةً لا تتطلب أدوات تغليف إضافية لتحقيق التصميم المطلوب.
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> _languages = ['English', 'German', 'French'];
String _language = 'English';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: DropdownButton2(
buttonStyleData: ButtonStyleData(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.blueAccent,
),
padding: const EdgeInsets.symmetric(horizontal: 10)
),
dropdownStyleData: DropdownStyleData(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.blueAccent,
),
),
iconStyleData: const IconStyleData(
icon: Icon(Icons.language),
iconSize: 30,
iconEnabledColor: Colors.white,
),
items: _languages
.map<DropdownMenuItem<String>>(
(String language) => DropdownMenuItem<String>(
value: language,
child: Text(language),
),
)
.toList(),
onChanged: (String? language) => setState(
() => _language = language ?? _language,
),
underline: const SizedBox.shrink(),
style: const TextStyle(
color: Colors.white,
fontSize: 20
),
value: _language,
),
),
),
);
}
}
في مقتطف التعليمات البرمجية أعلاه، أضفنا خمس سمات لتطبيق التصميم على نحو مماثل لما فعلناه باستخدام DropdownButton. لقد استخدمنا السمتين buttonStyleDataو dropdownStyleDataلتعيين ألوان وحدود الزر والقائمة المنسدلة إلى اللون الأزرق والمستدير. iconStyleDataتضيف السمة أيقونة لغة بيضاء إلى الزر. وأخيرًا، underlineتزيل السمة الخط السفلي، وتُستخدم styleالسمة لزيادة حجم النص وتغيير لون النص إلى الأبيض.
إذا قمنا ببناء تطبيقنا مرة أخرى، فسترى أن الزر والقائمة المنسدلة لهما تصميم مشابه. ومع ذلك، على عكس الأدوات المدمجة، لم نكن بحاجة إلى تغليف DropdownButton2الأداة بأدوات إضافية لتحقيق هذا التصميم.
أداة DropdownButtonFormField2
أخيرًا، لدينا DropdownButtonFormField2الأداة التي تعمل بشكل مشابه للأداة المضمنة DropdownButtonFormField. والفرق الرئيسي هو أن القائمة المنسدلة تظهر مباشرة أسفل الزر، إلى جانب سمات التصميم الإضافية.
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final List<String> _languages = ['English', 'German', 'French'];
String _language = 'English';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: SizedBox(
width: 200,
child: DropdownButtonFormField2(
buttonStyleData: const ButtonStyleData(
width: 110,
),
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
contentPadding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.blueAccent, width: 1.5),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.blueAccent, width: 2.5),
),
labelText: 'Language',
labelStyle: Theme.of(context).textTheme.titleMedium?.copyWith(fontSize: 18),
),
dropdownStyleData: DropdownStyleData(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
),
items: _languages
.map<DropdownMenuItem<String>>(
(String language) => DropdownMenuItem<String>(
value: language,
child: Text(language),
),
)
.toList(),
onChanged: (String? language) => setState(
() => _language = language ?? _language,
),
value: _language,
),
),
),
),
);
}
}
في مقتطف التعليمات البرمجية أعلاه، طبقنا نفس InputDecorationالمثيل على decorationالسمة كما فعلنا مع DropdownButtonFormFieldالمثال. وللحفاظ على المظهر مشابهًا، استخدمنا buttonStyleDataالسمة لمحاذاة اللغة المحددة إلى اليمين داخل الزر والسمة dropdownStyleDataلإضافة حدود مستديرة إلى القائمة المنسدلة.
خاتمة
في هذه المقالة، ناقشنا عدة طرق لتنفيذ القوائم المنسدلة في Flutter باستخدام الأدوات المدمجة: DropdownButton وPopupMenuButton وDropdownButtonFormField، بالإضافة إلى الأدوات المدمجة من حزمة Dropdown Button2. وبينما توفر الأدوات المدمجة العديد من الخيارات، توفر حزمة DropdownButton2 مرونة إضافية، مثل ضمان ظهور القائمة المنسدلة مباشرة أسفل الزر.