شارك المقالة
تعرف على مزايا HydratedBloc في Flutter لإدارة الحالة، وكيف يحافظ على البيانات بين جلسات التطبيق ويجعل تجربة المستخدم أفضل من الطرق التقليدية.

HydratedBloc في Flutter: شرح حفظ الحالة وإدارة State باحتراف


إدارة الحالة (State Management) من أهم التحديات في تطوير تطبيقات Flutter، خصوصًا عند الحاجة إلى الاحتفاظ ببيانات التطبيق بعد إغلاقه. هنا يأتي دور HydratedBloc كحل عملي وفعال يتيح حفظ الحالة تلقائيًا واستعادتها عند إعادة تشغيل التطبيق، مما يوفر تجربة مستخدم أكثر سلاسة واستقرارًا.


لماذا نستخدم HydratedBloc لحفظ الحالة في Flutter؟

في التطبيقات الحقيقية، يحتاج المستخدم إلى استكمال ما بدأه دون فقدان البيانات. بدلًا من إعادة تحميل الحالة أو استخدام حلول يدوية مثل SharedPreferences، يوفر HydratedBloc آلية ذكية لحفظ الحالة واسترجاعها تلقائيًا دون تعقيد.


ما هو HydratedBloc؟

HydratedBloc هو امتداد لمكتبة Bloc يضيف ميزة التخزين المحلي التلقائي للحالة. يعتمد على مكتبة hydrated_bloc التي تقوم بتخزين الحالة بصيغة JSON في التخزين المحلي باستخدام Hive أو SharedPreferences.

عند إعادة تشغيل التطبيق، يتم استعادة آخر حالة محفوظة تلقائيًا دون أي تدخل من المطور.


عندما يتم إغلاق التطبيق أو إعادة تشغيله، يتم حفظ الحالة الحالية في التخزين المحلي، ويمكن استعادتها عند تشغيل التطبيق مرة أخرى. هذا يجعل HydratedCubit أداة مثالية للتطبيقات التي تحتاج إلى الحفاظ على بيانات المستخدم أو حالة التطبيق بين الجلسات.

كيفية تثبيت hydrated_bloc في مشروع Flutter

أضف الاعتمادات التالية إلى ملف pubspec.yaml:


dependencies:
  flutter:
    sdk: flutter
  hydrated_bloc: ^8.0.0
  path_provider: ^2.0.11

تهيئة HydratedBloc عند تشغيل التطبيق

قبل استخدام HydratedCubit أو HydratedBloc، يجب تهيئة التخزين في نقطة بدء التطبيق:


void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  HydratedBloc.storage = await HydratedStorage.build(
    storageDirectory: await getTemporaryDirectory(),
  );

  runApp(const MyApp());
}

استخدام HydratedCubit مع Cubit


class CounterCubit extends HydratedCubit {
  CounterCubit() : super(const CounterInit());

  void increment() {
    emit(CounterUpdate(state.count + 1));
  }

  void decrement() {
    emit(CounterUpdate(state.count - 1));
  }

  @override
  CounterState? fromJson(Map json) {
    return CounterUpdate(json['count']);
  }

  @override
  Map? toJson(CounterState state) {
    return {'count': state.count};
  }
}

في هذا المثال:

  • يتم حفظ قيمة العداد تلقائيًا
  • fromJson تُستخدم لاستعادة الحالة
  • toJson تُستخدم لحفظ الحالة في التخزين المحلي

استخدام HydratedBloc مع Bloc


class TaskBloc extends HydratedBloc {
  TaskBloc() : super(TaskInitial()) {
    on(_addTask);
    on(_removeTask);
    on(_toggleTask);
  }

  void _addTask(AddTaskEvent event, Emitter emit) {
    final task = TaskModel(
      id: const Uuid().v4(),
      title: event.title,
      isCompleted: false,
    );
    emit(UpdateTask([...state.tasksList, task]));
  }

  void _removeTask(RemoveTaskEvent event, Emitter emit) {
    emit(UpdateTask(
      state.tasksList.where((t) => t.id != event.id).toList(),
    ));
  }

  void _toggleTask(ToggleTaskEvent event, Emitter emit) {
    emit(UpdateTask(
      state.tasksList.map((task) {
        return task.id == event.id
            ? task.copyWith(isCompleted: !task.isCompleted)
            : task;
      }).toList(),
    ));
  }

  @override
  TaskState? fromJson(Map json) {
    return UpdateTask(
      (json['tasks'] as List)
          .map((e) => TaskModel.fromJson(e))
          .toList(),
    );
  }

  @override
  Map? toJson(TaskState state) {
    return {
      'tasks': state.tasksList.map((e) => e.toJson()).toList(),
    };
  }
}

تعريف حالة المهام (State)


abstract class TaskState {
  final List tasksList;
  TaskState(this.tasksList);
}

class TaskInitial extends TaskState {
  TaskInitial() : super([]);
}

class UpdateTask extends TaskState {
  UpdateTask(List tasksList) : super(tasksList);
}

متى لا يكون HydratedBloc هو الخيار المناسب؟


  • عند التعامل مع بيانات حساسة (مثل كلمات المرور)
  • عند الحاجة إلى تخزين مؤقت فقط
  • في الحالات التي تتطلب مزامنة فورية مع السيرفر

مزايا استخدام HydratedBloc في Flutter

  • حفظ واستعادة الحالة تلقائيًا
  • تقليل الكود المتكرر
  • تحسين تجربة المستخدم
  • تكامل مثالي مع Bloc

أسئلة شائعة حول HydratedBloc

هل HydratedBloc يؤثر على أداء التطبيق؟

لا، يتم التخزين بطريقة غير متزامنة ولا يؤثر بشكل ملحوظ على الأداء.

هل يمكن استخدام HydratedBloc مع Riverpod؟

لا، HydratedBloc مصمم خصيصًا للعمل مع Bloc و Cubit.

شاهد أيضًا
مقالات ذات صلة
navigation drawer بجميع تفاصيلها في Flutter بالعربي

navigation drawer بجميع تفاصيلها في Flutterيعد الnavigation drawer من العناصر الاساسيه في التطبيقات وهو بكل…

اظهار تقيم لعناصر التطبيق الخاص بك بجميع التقيمات في Flutter

اظهار تقيم لعناصر التطبيق الخاص بك بجميع التقيمات في Flutter في هذا المقال نشارك معكم…

انشاء Dialog Fragment واستدعاءة في activity او fragment على شكل dialog

  انشاء Dialog Fragment واستدعاءة في activity او fragment على شكل dialogفي كثير من الاحيان…

🚫 مانع الإعلانات مفعل

يجب إيقاف مانع الإعلانات لاستكمال تصفح الموقع