شرح كيفية اضافة وعرض البيانات في Todo app بإستخدام Bloc في Flutter #3

 

شرح كيفية اضافة وعرض البيانات في Todo app بإستخدام Bloc

شرح كيفية اضافة وعرض البيانات في Todo app بإستخدام Bloc


في هذا المقال سوف نتعرف معكم على كيفية اضافة بيانات وعرض البيانات بإستخدام الBloc وهذه الطريقة هي الطريقة التي يتم عرض البيانات بعد اضافتها بشكل مباشر بدلا من اغلاق التطبيق وفتحه مره اخرى ولهذا عليك بإستخدام البلوك وقد سبق ووضعنا لكم مقدمه وشرح عن استخدام الbloc وهذا الدرس يعد تابع للدروس السابقة وسوف نقوم بتحويل الكود من الشكل العادي الى الcubit وهذا الحل يعد الافضل .


لغة الدرات هي لغة oop من اللغات عالية المستوى والتي تسهل على المطور التعامل مع عدة classes من اجل تنظيم العمل وهي لغة قريبة من java  و python بشكل كبير اي انها قريبة من جافا وبايثون فإذا كنت قد تعاملت مع اي لغة منهم سابقا سيكون الامر بسيط بالنسبة لك بشكل كبير وايضا سنحاول من خلال المقالات شرح الاكواد المقدمه لكي تسهل عليكم الفهم واسترجاع المعلومه .


نقدم في موقعنا المتواضيع مجموعة كبيره من الاكواد البرمجية المختلفه ولا يقتصر الموقع فقط على الاكواد البسيطه فيوجد لدينا كورسات قوية في اللغات وتطوير التطبيقات وكل هذا بالمجان ، وبدعمكم للموقع سنحاول توفير في الايام المقبله شروحات مصوره من اجل فهم الاكواد بشكل افضل ولدينا عدد من الدروس في موقعنا بالفيديو .


اضافة حالات للCubit في ملف states


في هذا الملف سوف نقوم بعمل الحالات المهمه وسوف نقوم بزيادة الحالات واحده تلو الاخرى في الدروس المقبلة ولكن ما يهمنا هو اضافة البيانات المهمه فقط وتحويلها الى States ولهذا سوف نقوم بعمل بعض الحالات المستخدمه في الدروس السابقة ولكن بعد تحويلها الى Cubit


محتويات ملف states.dart


اضافة حالات للCubit في ملف states

states.dart


abstract class AppStates {}

class AppInitialState extends AppStates {}

class AppChangeBottomNav extends AppStates {}

class AppCreateDataBaseState extends AppStates {}

class AppGetDataBaseLoadingState extends AppStates {}

class AppInsertDataBaseState extends AppStates {}


محتويات ملف Cubit.dart


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


شرح كيفية اضافة وعرض البيانات في Todo app بإستخدام Bloc

cubit.dart


class AppCubit extends Cubit<AppStates> {

  AppCubit () : super (AppInitialState());
  static AppCubit get(context) => BlocProvider.of(context);


  int currentIndex = 0;
  late Database database;
  List<Map> tasks = [];
  bool isBottomSheetShow = false;
  IconData iconData = Icons.edit;

  List<Widget> screen = [
    NewTask(),
    DoneTask(),
    ArchivedTask(),
  ];

  List<String> appbar = [
    'NewTask',
    'DoneTask',
    'ArchivedTask',
  ];

  void changeIndex(int index) {
      currentIndex = index;
      emit(AppChangeBottomNav());
  }

void create_db() async {

openDatabase('note.db', version: 1,
onCreate: (database, version) {
print('DataBase is Created');
database
.execute(
'CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT , date TEXT , time TEXT , status TEXT)')
.then((value) {
print('Table Created');
}).catchError((error) {
print('Error ${error.toString()}');
});
}, onOpen: (database) {
getDataFromDB(database).then((value) {
tasks = value;
print(tasks);
emit(AppGetDataBaseState());
});
print('DataBase is Opened');
}).then((value) {
database = value;
emit(AppCreateDataBaseState());
});
}

  Future<List<Map>> getDataFromDB(database) async
  {
    // تشغيل الانتظار الى وصول البيانات
    emit(AppGetDataBaseLoadingState());
    return await database!.rawQuery('SELECT * FROM tasks');
  }

   insert_database({
    required String title,
    required String time,
    required String date,
  }) async {
    
await database.transaction((txn) {
return txn
.rawInsert(
'INSERT INTO tasks(title , time , date , status) VALUES( "$title" , "$time" , "$date" , "active" )')
.then((value) {
print('done $value');
emit(AppInsertDataBaseState());

getDataFromDB(database).then((value) {
tasks = value;
print(tasks);
emit(AppGetDataBaseState());
        });

      }).catchError((onError){
        print('Error ${onError.toString()}');

      });
    });

  }

  void changeBottomSheetState({
  required bool isShow,
  required IconData icon,
  
}) {
  
  isBottomSheetShow = isShow;
  iconData = icon;
  emit(AppChangeBottomSheetState());
  
  }
}


محتويات ملف NewTask


محتويات ملف NewTask

الان ارجع للملف المخصص لعرض البيانات وقم بتعديله الى الكود التالي وهو بكل اختصار تحويله الى حالة الcubit لكي يمكن تنفيذه ومتغير الcubit يحتوي على الاوامر الرئيسيه وهيا builder و listener .



class NewTask extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return BlocConsumer<AppCubit , AppStates>(
        listener: (context , state){},
        builder: (context , state){
          var tasks = AppCubit.get(context).tasks;
      
          return ListView.separated(
              itemBuilder: (context , value) => buildTaskItem(tasks[value]),
              separatorBuilder: (context , value) => Padding(
                padding: const EdgeInsetsDirectional.all(10),
                child: Container(
                  width: double.infinity,
                  height: 1,
                  margin: EdgeInsetsDirectional.only(start: 20),
                  color: Colors.grey[300],
                ),
              ),
              itemCount: tasks.length);
        },
    );
  }
}


محتويات ملف Home_Screen


محتويات ملف Home_Screen


الان في ملف Home_Screen سوف نقوم بإستدعاء تشغيل الcubit وهو الذي سوف يقوم بتشغيل البيانات وتحديثها في اكثر من مره على الاستخدام ولهذا يفضل كتابة اكوادك داخل cubit وقد سبق ووضعنا لكم شروحات عنها بالنسبة للBlocProvider يتم استدعاءه مره واحده فقط اماا الBlocConsumer يتم استدعاءه في الملف الذي تريد تشغيل الcubit بداخله .


class Home_Screen extends StatelessWidget {

  var scaffoldKey = GlobalKey<ScaffoldState>();
  var formKey = GlobalKey<FormState>();
  var title_controller = TextEditingController();
  var time_controller = TextEditingController();
  var date_controller = TextEditingController();

  @override
  Widget build(BuildContext context) {

    // استخدام .. هي عمل اكسس للappcubit والوصول الى محتوياته بمعنى قمنا بجعله مثل المتغير
    return BlocProvider(
      create: (BuildContext context) => AppCubit()..create_db(),

      child: BlocConsumer<AppCubit , AppStates>(
        listener: (BuildContext context, state) {
          if (state is AppInsertDataBaseState) {
            Navigator.pop(context);
          }
        },
        builder: (BuildContext context, state) {
          var def = AppCubit.get(context);
          return Scaffold(
          key: scaffoldKey,
          appBar: AppBar(
          title: Text(
              def.appbar[def.currentIndex]
          ),
          ),
          body: state is AppGetDataBaseLoadingState ? Center(child: CircularProgressIndicator()) : AppCubit.get(context).screen[AppCubit.get(context).currentIndex],
          floatingActionButton: FloatingActionButton(
          onPressed: () async {
          if (def.isBottomSheetShow) {
          if (formKey.currentState!.validate()) {
            def.insert_database(
                title: title_controller.text,
                time: time_controller.text,
                date: date_controller.text);
          }

          } else {
          scaffoldKey.currentState!.showBottomSheet((context) => Padding(
          padding: const EdgeInsets.all(15.0),
          child: Form(
          key: formKey,
          child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
          defaultFormField(controller: title_controller,
          type: TextInputType.text,
          validate: (String? value){
          if (value!.isEmpty) {
          return 'title is null';
          }
          return null;
          },
          label: 'Task Title',
          prefix: Icons.title),

          SizedBox(height: 5,),
          defaultFormField(controller: time_controller,
          type: TextInputType.datetime,
          onTap: (){
          showTimePicker(context: context,
          initialTime: TimeOfDay.now())
              .then((value) {
             time_controller.text = value!.format(context);
          print(value.toString());
          });
          },
          validate: (String? value){
          if (value!.isEmpty) {
          return 'time is null';
          }
          return null;
          },
          label: 'Task Time',
          prefix: Icons.timer_sharp),
          SizedBox(height: 5,),
          defaultFormField(controller: date_controller,
          type: TextInputType.datetime,
          onTap: (){
          showDatePicker(context: context,
          initialDate: DateTime.now(),
          firstDate: DateTime(2018),
          lastDate: DateTime(2025)).then((value) {
          date_controller.text = DateFormat.yMMMd().format(value!);
          print(value.toString());
          });

          },
          validate: (String? value){
          if (value!.isEmpty) {
          return 'time is null';
          }
          return null;
          },
          label: 'Task Time',
          prefix: Icons.timer_sharp),
          ],
          ),
          ),
          ),
          elevation: 20.0,
          ).closed.then((value) {
          def.changeBottomSheetState(
              isShow: false,
              icon: Icons.edit
          );
          });
         def.changeBottomSheetState(isShow: true,
             icon: Icons.add);
          }
          },
          child: Icon(def.iconData),
          ),
          bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          elevation: 100.0,
          currentIndex: def.currentIndex,
          onTap: (index) {
         def.changeIndex(index);
          // setState(() {
          //   currentIndex = index;
          // });
          },
          items: [
          BottomNavigationBarItem(
          icon: Icon(Icons.menu_rounded), label: 'Text'),
          BottomNavigationBarItem(
          icon: Icon(Icons.check_circle_outline), label: 'Done'),
          BottomNavigationBarItem(
          icon: Icon(Icons.archive_outlined), label: 'Archive'),
          ],
          ),
          );
        },

      ),
    );
  }

}


لمزيد من الاكواد في فلاتر يمكنك مشاهدة احد المقالات التالية :


تعليقات