ما هو SnackBar؟
SnackBar هو ويدجت من مكتبة Material في Flutter لعرض رسالة خفيفة مؤقتة في أسفل الشاشة، غالبًا مع زر إجراء اختياري (مثلاً “Undo”). الهدف: إعلام المستخدم بسرعة دون إيقاف تفاعله مع التطبيق. Flutter API Docs+1
كيف أُظهر SnackBar (الطريقة الموصى بها)
إنشئ SnackBar ثم أعرضه عبر ScaffoldMessenger:
final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);PHP ScaffoldMessenger.of(context).showSnackBar(SnackBar(
padding: EdgeInsets.all(50),
action: SnackBarAction(label: "label", onPressed:(){}),
duration: Duration(seconds: 10),
showCloseIcon: true,
dismissDirection: DismissDirection.endToStart,
backgroundColor: Colors.red,
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(50),
closeIconColor: Colors.amber,
content: Text("data")));PHPهذا هو الأسلوب الرسمي الآن (لم يعد يُنصح باستخدام Scaffold.of(context).showSnackBar) ولديك خيار استخدام مفتاح عام (scaffoldMessengerKey) في MaterialApp إذا أردت التحكم من خارج الـBuildContext. Flutter Docs+1
الخصائص (properties) المهمة — شرح مرتب للمبتدئ
(الإشارة: هذه الخصائص هي معاملات منشئ
SnackBarكما في توثيق Flutter). Flutter API Docs
content(مطلوب)
الـ widget الذي يظهر داخل الـSnackBar — عادةًText(...). Flutter API Docsaction(SnackBarAction?)
زر واحد اختياري يظهر بجانب الرسالة (مثال:label: 'Undo',onPressed: () { ... }). يمكن تخصيص لون النص عبرtextColor. Flutter API Docs+1duration(Duration)
المدة التي يبقى فيها الـSnackBar ظاهرًا — الافتراضي هو 4.0 ثواني. ملاحظة: إذا كان هناكactionفقد يتصرف الوصول (accessibility) بحيث لا يُغلق تلقائيًا على بعض إعدادات المساعد الصوتي. Flutter API Docs+1behavior(SnackBarBehavior)
يحدّد موضع وسلوك الـSnackBar:fixed(ملتصق بعرض الشاشة) أوfloating(مستقل، يسمح بـmarginوshape). الافتراضيfixed. استخدمfloatingلتصميم أصغر مع زوايا مستديرة ومصاريف حوله. Flutter API Docsmargin,padding,width,shape,elevation,backgroundColor
عناصر تخصيص الشكل والمكان والظل. ملاحظة:marginيُطبق فقط عندما تكونbehavior = SnackBarBehavior.floating، وwidthوmarginلا يمكن استخدامهما معًا (assert في البناء).elevationيؤثر على الظل، خصوصًا عندfloating. Flutter API Docs+1padding(قيمة افتراضية مفصّلة)
إذا لم تُعطَ padding، فهناك قواعد افتراضية (مثلاً: top/bottom = 14; left = 24 عندماfixedو16 عندماfloating; وright = left إذا لم يكن هناك action، وإلا 0). هذه التفاصيل مهمة عند تصميم النص وطريقة لفّه. Flutter API DocsactionOverflowThreshold(double بين 0 و1)
تحدد متى يُنقل زر الـ action إلى سطر جديد إذا كان طول المحتوى كبيرًا. القيمة الافتراضية = 0.25 (أي إذا شغل المحتوى أكثر من 25% من المساحة المتبقية اختار وضع الزر بأسفل). Flutter API DocsshowCloseIconوcloseIconColor
خيار لعرض أيقونة إغلاق صغيرة داخل الـSnackBar مع تخصيص لونها. Flutter API DocsonVisibleوanimationonVisibleيتم استدعاؤها عند الظهور لأول مرة — مفيدة لتنفيذ لوجيك وقت العرض. يمكنك أيضاً تمريرanimationمخصّصة إذا أردت التحكم بمدخل/خروج الظهور. Flutter API DocsdismissDirection(DismissDirection)
تحديد اتجاه السحب الذي يسمح للمستخدم بإغلاق الـSnackBar (مثلاًdown,horizontal,none…). الافتراضي إذا لم تُعرّف فهوDismissDirection.down. Flutter API DocshitTestBehavior
يحدد كيف تتعامل المنطقة (بما في ذلك المسافات الخارجيةmargin) مع اللمسات/النقرات — قيم مثلdeferToChild,opaque,translucent. هذا مهم إذا كان الـSnackBar يغطّي عناصر قابلة للنقر. Flutter API Docs
إدارة الإغلاق ونتائج الإغلاق
عند استدعاء showSnackBar تحصل على ScaffoldFeatureController<SnackBar, SnackBarClosedReason>، يمكنك استخدامه لـ:
.close()أوScaffoldMessenger.of(context).hideCurrentSnackBar()لإغلاق مع أنيميشن خروج.removeCurrentSnackBar()لإزالة فوري بدون أنيميشن.- الاستماع إلى
controller.closedلمعرفة سبب الإغلاق (SnackBarClosedReason) (مثلاً:action،timeout,dismiss). Flutter API Docs+1
أمثلة عملية (جاهزة للنسخ)
1) أبسط مثال:
ElevatedButton(
onPressed: () {
final snackBar = SnackBar(content: Text('تم الحفظ!'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
},
child: Text('أظهر SnackBar'),
)PHP(مأخوذ من وصف الاستخدام في Flutter cookbook). Flutter Docs
2) مع إجراء Undo والانتظار لمعرفة سبب الإغلاق (مفيد للتراجع عن حذف):
final controller = ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('تم حذف العنصر'),
action: SnackBarAction(label: 'Undo', onPressed: () {
// فعل التراجع هنا
}),
duration: Duration(seconds: 4),
),
);
// معرفة نتيجة الإغلاق (مثلاً commit الحذف إذا لم يضغط المستخدم Undo)
controller.closed.then((reason) {
if (reason != SnackBarClosedReason.action) {
// لا يوجد تراجع — قم بتطبيق الحذف النهائي
}
});
PHP(تذكّر: showSnackBar يرجع ScaffoldFeatureController مع مستقبل closed). Flutter API Docs+1
3) SnackBar مخصّص عائم (floating) بشكل مستدير وزر إغلاق:
final snack = SnackBar(
content: Row(
children: [
Icon(Icons.info_outline),
SizedBox(width: 8),
Expanded(child: Text('رسالة مهمة قصيرة')),
],
),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
backgroundColor: Colors.blueAccent,
showCloseIcon: true,
closeIconColor: Colors.white,
action: SnackBarAction(
label: 'حسناً',
onPressed: () {},
),
);
ScaffoldMessenger.of(context).showSnackBar(snack);
PHP(ملاحظة: margin يعمل فقط مع behavior = floating). Flutter API Docs+1
ثيم/تخصيص عام (Theme)
لو تريد نمطًا موحّدًا لكل الـSnackBars في التطبيق، استخدم SnackBarThemeData داخل ThemeData (مثلاً تغيير backgroundColor, actionTextColor, behavior, actionOverflowThreshold, dismissDirection…) — هذا يسهل المحافظة على تناسق الواجهات. Flutter API Docs
نصائح عملية / أفضل ممارسات للمبتدئين
- اجعل الرسائل قصيرة وواضحة (سطر واحد أو سطرين كحد أقصى). (مبدأ تصميم Material للـSnackbars). Material Design
- استخدم زر
actionفقط لإجراءات سريعة قابلة للتراجع (مثل Undo)، وليس لإجراءات معقّدة. Flutter API Docs - إن أردت إشعارًا أكثر أهمية أو تفاعلاً مع خيارات متعددة استخدم
DialogأوBottomSheetبدل SnackBar. - لا تضع SnackBar فوق عناصر مهمة دون Margin/behavior مناسب حتى لا يحجب عناصر UI قابلة للتفاعل. Flutter API Docs+1