✅
BlocProvider
✅BlocBuilder
خليني أشرحهم لك بعمق + منطق + كود + كيف يشتغلوا مع بعض
🧩 أولًا: BlocProvider
🎯 ما وظيفته؟
👉 هو المسؤول عن:
إنشاء الـ Cubit وتوفيره (Inject) لباقي التطبيق
بمعنى:
يخلي أي Widget داخل الشجرة يقدر يوصل للـ Cubit
🔧 شكله في الكود
BlocProvider(
create: (context) => CounterCubit(),
child: HomePage(),
)
🧠 ماذا يحدث هنا؟
1️⃣ إنشاء Cubit
create: (context) => CounterCubit()
👉 يتم إنشاء نسخة من:
CounterCubit()
2️⃣ توفيره في الشجرة (Widget Tree)
BlocProvider
↓
HomePage
↓
أي Widget داخلها
👉 كل Widget تحت HomePage يمكنه الوصول للـ Cubit
📥 كيف نصل للـ Cubit؟
داخل أي Widget:
context.read<CounterCubit>()
أو:
BlocProvider.of<CounterCubit>(context)
🔥 مثال عملي
زر زيادة:
ElevatedButton(
onPressed: () {
context.read<CounterCubit>().increment();
},
child: Text("زيادة"),
)
⚠️ بدون BlocProvider؟
❌ سيحدث خطأ:
BlocProvider.of() called with a context that does not contain a Bloc
💡 خلاصة BlocProvider
| الوظيفة | الشرح |
|---|---|
| إنشاء Cubit | create |
| توفيره | لكل الشجرة |
| الوصول له | context.read |
🧩 ثانيًا: BlocBuilder
🎯 ما وظيفته؟
👉 هو المسؤول عن:
الاستماع للتغييرات (emit) وإعادة بناء الواجهة
🔧 شكله في الكود
BlocBuilder<CounterCubit, CounterState>(
builder: (context, state) {
return Text("${state.counter}");
},
)
🧠 ماذا يحدث هنا؟
1️⃣ يستمع للـ Cubit
CounterCubit
2️⃣ ينتظر أي emit
emit(CounterState(...))
3️⃣ عند وصول حالة جديدة
👉 يتم تشغيل:
builder(context, state)
🔄 دورة العمل
emit() → BlocBuilder يسمع → يعيد بناء UI
🔥 مثال حي
BlocBuilder<CounterCubit, CounterState>(
builder: (context, state) {
return Column(
children: [
Text("${state.counter}"),
ElevatedButton(
onPressed: () {
context.read<CounterCubit>().increment();
},
child: Text("زيادة"),
),
],
);
},
)
🧠 ماذا يحدث عند الضغط؟
- الضغط على الزر
- استدعاء
increment() - داخلها
emit() - BlocBuilder يسمع
- يعيد بناء Text
- يظهر الرقم الجديد
🔗 العلاقة بين BlocProvider و BlocBuilder
🧩 كيف يعملوا مع بعض؟
BlocProvider → يوفر Cubit
BlocBuilder → يسمع من Cubit
🔄 التسلسل الكامل
BlocProvider
↓
CounterCubit (state = 0)
↓
BlocBuilder (يعرض 0)
↓
زر + يضغط
↓
increment()
↓
emit(1)
↓
BlocBuilder يعيد البناء
↓
يعرض 1
⚠️ الفرق المهم جدًا
| العنصر | الوظيفة |
|---|---|
| BlocProvider | إنشاء + توفير |
| BlocBuilder | عرض + تحديث |
🔥 مثال كامل (مهم جدًا)
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CounterCubit(),
child: Scaffold(
body: Center(
child: BlocBuilder<CounterCubit, CounterState>(
builder: (context, state) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("${state.counter}"),
ElevatedButton(
onPressed: () {
context.read<CounterCubit>().increment();
},
child: Text("زيادة"),
),
],
);
},
),
),
),
);
}
}
🧠 ملاحظات احترافية
✅ read vs watch
| الطريقة | متى تستخدمها |
|---|---|
read | تنفيذ دالة (بدون rebuild) |
watch | الاستماع للتغييرات |
✅ BlocBuilder لا يُنشئ Cubit
👉 فقط يستمع
✅ يمكن استخدام أكثر من BlocProvider
MultiBlocProvider(
providers: [
BlocProvider(create: (_) => CounterCubit()),
BlocProvider(create: (_) => AnotherCubit()),
],
child: MyApp(),
)
💥 الخلاصة النهائية
BlocProvider= يعطيك CubitBlocBuilder= يسمع ويحدث الواجهةemit= يرسل التحديث