ما هو ElevatedButton؟
زر Material “مرفوع” بظل خفيف، مناسب للأفعال الأساسية (Primary Action). هو البديل الحديث لـ RaisedButton
(الموقوف). سلوكه يتغيّر حسب الحالة (عادي، Hover، Focus، Pressed، Disabled).
البُنى (Constructors)
ElevatedButton
(القياسي):
ElevatedButton(
onPressed: () {},
onLongPress: () {},
child: Text('اضغط'),
)
DartElevatedButton.icon
(مع أيقونة ونص):
ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.send),
label: Text('إرسال'),
)
Dartتعطيل الزر: اجعل onPressed: null
أهم الخصائص المباشرة
الخاصية | الوصف |
---|---|
onPressed / onLongPress | دوال الاستجابة للنقر والضغط المطوّل |
child / icon + label | محتوى الزر |
style | تخصيص المظهر عبر ButtonStyle |
autofocus , focusNode , clipBehavior | وصول لوحة المفاتيح والقص |
التخصيص السريع: styleFrom
أسهل طريقة لتخصيص سريع (ينتج ButtonStyle
جاهز):
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue, // لون الخلفية
foregroundColor: Colors.white, // لون النص/الأيقونة
elevation: 3, // الظل
shadowColor: Colors.black54,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 14),
minimumSize: Size(120, 48), // أصغر مقاس
fixedSize: Size.fromHeight(48), // مقاس ثابت (اختياري)
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
side: BorderSide(color: Colors.blueGrey), // حدود
),
child: Text('زر مخصص'),
)
Dartملاحظة (M3): أحيانًا يظهر تأثير Surface Tint الافتراضي من الثيم. إن لم ترغب به عدّله عبر الثيم أو
ButtonStyle
(انظر أدناه).
التخصيص الاحترافي: ButtonStyle
+ MaterialStateProperty
لجعل المظهر يتغيّر حسب الحالة (hover/pressed/disabled…):
ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color?>((states) {
if (states.contains(MaterialState.disabled)) return Colors.grey.shade400;
if (states.contains(MaterialState.pressed)) return Colors.blue.shade700;
if (states.contains(MaterialState.hovered)) return Colors.blue.shade600;
return Colors.blue; // عادي
}),
foregroundColor: MaterialStateProperty.all(Colors.white),
overlayColor: MaterialStateProperty.resolveWith<Color?>((states) {
if (states.contains(MaterialState.pressed)) return Colors.white.withOpacity(0.12);
if (states.contains(MaterialState.hovered)) return Colors.white.withOpacity(0.06);
return null; // الافتراضي
}),
elevation: MaterialStateProperty.resolveWith<double>((states) {
if (states.contains(MaterialState.disabled)) return 0;
if (states.contains(MaterialState.pressed)) return 8;
if (states.contains(MaterialState.hovered)) return 4;
return 2;
}),
padding: MaterialStateProperty.all(const EdgeInsets.symmetric(horizontal: 20, vertical: 14)),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
),
minimumSize: MaterialStateProperty.all(const Size(120, 48)),
// يمكن أيضًا: foregroundColor, shadowColor, surfaceTintColor, side, textStyle, alignment ...
),
child: const Text('زر بحالات متعددة'),
)
Dartأهم حقول ButtonStyle
المفيدة
textStyle
: خط النص.backgroundColor
,foregroundColor
: ألوان الخلفية والنص/الأيقونات.overlayColor
: لون طبقة التفاعل (ضغط/هوفر).shadowColor
,elevation
: لون الظل وارتفاعه.surfaceTintColor
(في Material 3): تينت سطح الزر.padding
,minimumSize
,fixedSize
,maximumSize
.shape
,side
: الشكل والحدود.animationDuration
,enableFeedback
,alignment
,visualDensity
,tapTargetSize
.
قاعدة ذهبية: استخدم
resolveWith
عندما تريد سلوكًا متغيرًا حسب الحالة.
أمثلة جاهزة مهمة
1) زر بعرض الشاشة (Block Button)
- الطريقة 1 (مباشرة): dartCopyEdit
SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () {}, child: Text('متابعة'), ), )
- الطريقة 2 (من خلال الـ style): dartCopyEdit
ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom(minimumSize: const Size.fromHeight(48)), child: const Text('متابعة'), )
2) زر مع أيقونة ونص
ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.save),
label: const Text('حفظ'),
style: ElevatedButton.styleFrom(padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12)),
)
Dart3) زر تحميل (حالة انتظار)
class SaveButton extends StatefulWidget {
const SaveButton({super.key});
@override
State<SaveButton> createState() => _SaveButtonState();
}
class _SaveButtonState extends State<SaveButton> {
bool loading = false;
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: loading ? null : () async {
setState(() => loading = true);
await Future.delayed(const Duration(seconds: 2));
setState(() => loading = false);
},
style: ElevatedButton.styleFrom(minimumSize: const Size(140, 48)),
child: loading
? const SizedBox(
width: 22, height: 22,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Text('حفظ'),
);
}
}
Dart4) زر بحواف كابسول وحدود
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
side: const BorderSide(color: Colors.indigo),
),
child: const Text('Capsule'),
)
Dart5) جعل الزر شفافًا فوق خلفية متدرجة (حيلة)
لا يوجد Gradient مباشر للخلفية؛ استخدم حاوية بالخلفية، واجعل الزر شفاف الظل/الخلفية:
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(colors: [Colors.purple, Colors.blue]),
borderRadius: BorderRadius.all(Radius.circular(14)),
),
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
minimumSize: const Size.fromHeight(48),
),
child: const Text('زر متدرّج'),
),
)
Dart6) استخدامه داخل Row
مع توزيع المساحة
Row(
children: [
Expanded(
child: ElevatedButton(onPressed: () {}, child: const Text('يسار')),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton(onPressed: () {}, child: const Text('يمين')),
),
],
)
Dartالتيمـة (Theme) — توحيد مظهر الأزرار
اضبط شكل جميع أزرار التطبيق من مكان واحد:
MaterialApp(
theme: ThemeData(
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
minimumSize: const Size(120, 48),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
textStyle: const TextStyle(fontWeight: FontWeight.w600),
),
),
// في Material 3 يمكن التحكم بـ colorScheme + surfaceTintColor
// useMaterial3: true,
),
home: const MyHomePage(),
);
Dartلتغيير الألوان حسب ColorScheme (الموصى به مع Material 3)، اعتمد على
colorScheme.primary
وonPrimary
بدل الألوان الصريحة.
أفضل الممارسات
- (حديث) فضّل
ElevatedButton
/TextButton
/OutlinedButton
على الأزرار القديمة مثلRaisedButton
وFlatButton
. - استخدم
styleFrom
للتخصيص السريع، وButtonStyle
+MaterialStateProperty
للحالات المعقدة. - لإشارة التعطيل، اجعل
onPressed: null
— ستطبَّق ألوان وتعطيل مناسب تلقائيًا. - للأزرار داخل Column مع عناصر أخرى، استخدم
SizedBox
أوExpanded
لتحديد الارتفاع/التمدد وتجنّب أخطاء القياس. - عند الحاجة لتلميح (Tooltip) على سطح المكتب/الويب، لف الزر بـ
Tooltip
: dartCopyEditTooltip(message: 'حفظ', child: ElevatedButton(onPressed: () {}, child: Text('حفظ')))
- للأداء والوضوح، استخدم
const
حيثما أمكن فيchild
.
مقارنة سريعة (متى أستخدم ماذا؟)
- ElevatedButton: الفعل الأساسي (Primary) أو حيث يلزم تباين قوي/ظل.
- TextButton: أفعال ثانوية بلا حدود/ظل (روابط، “تعلّم المزيد”).
- OutlinedButton: أفعال ثانوية بحدّ واضح بدون تعبئة.