إنشاء BottomNavBar بإستخدام bloc cubit في Flutter

 

إنشاء BottomNavBar بإستخدام bloc cubit في Flutter

إنشاء BottomNavBar بإستخدام bloc cubit في Flutter


في الدرس السابق تعرفنا على تقنية bloc وال cubit ومدى اهميتها في التطبيق الخاص بنا وفي هذا الدرس سوف نضع لكم اول مثال بإستخدام الcubit وهو بعنوان كيفية انشاء شريط التنقل السفلي بواسطة bloc حيث ان تعلمك للbloc سوف يفيدك في كثير من الاحيان على سبيل المثال اذا كنت تريد إنشاء تطبيق ملاحظات وهذا ما سنعمل عليه في قائمة Database سوف تحتاج الى عمل cubit وذلك لان كل اضافة احذف تحتاج الى تحديث الصفحة الرئيسيه .


تعتبر لغة dart مخصصه ل flutter و فلاتر مخصصة لتطوير و صناعة تطبيقات اندرويد او الايفون ونحن نعمل على تقديم شرح لكل من يريد تعلم دارت و برمجة و تطوير التطبيقات ios , android , web او غيرها ويمكنك تحميل حزمة sdk من خلال الانتقال الى الموقع الخاص بهم وعمل download وتثبيته والبدء في انشاء اول app او برنامج لك وسوف نعمل على تقديم دورة لعمل العديد من أفضل التطبيقات وكل شيئ تقريبا حول هذة اللغه وتقديم لكم كتاب في الدارت لتطوير من نفسك حيث يوجد الكثير من كتب development ولكن سوف نقدم لكم افضل كتاب عربي في تعلم الدارت والفلاتر


ما المميز في إطار العمل الخاص بفلاتر


يمكنك عمل تطبيق خاص بك و الـ apps التي يتم كتابها باستخدام language dart تعمل على مختلف المنصات ويمكنك البحث في جوجل عن طريق الانتقال الى google والبحث لماذا بناء التبيطقات بفلاتر ويوجد شركة او العديد من الشركات تهتم ب كيفية العمل بفلاتر وال ui لانه تستطيع من خلال flutter تطوير العديد من التطبيقات بكود واحد بالعربي او الانجليزي لكي تكون البداية لديك قوية ويمكنك الاستعانه بي المصدر ال مستخدم من موقع فلاتر .


محتويات ملف states


علينا في البداية عمل الكلاس من نوع abstract  وبعدها سوف نقوم بعمل AppInitialState وهي لتثبيت الcubit وتشغيله وبعدها سوف ننشأ كلاس اخر للتنقل اسفله بإسم AppChangeBottomNav .


ما المميز في إطار العمل الخاص بفلاتر


states.dart 


abstract class AppStates {}

class AppInitialState extends AppStates {}

class AppChangeBottomNav extends AppStates {}


محتويات ملف cubit


محتويات ملف cubit


هذا الكلاس يعد الكلاس الرئيسي وهو الذي يتم بداخلة كتابة الاكواد التي تريدها ان تعمل في cubit , سوف تقوم اولا بتعريف اسم الكلاس بشكل كامل , بعدها سوف تقوم بعمل قائمة من نوع Widget باسم screen لكي يتم تغيير الواجهه عند النقر على اي من العناصر او الاسماء السفلية , وقائمة اخرى تحتوي على اسماء الappbar , واخيرا قم بعمل methode تحتوي على امكانية التغيير ولا تنسى عمل بداخلها emit للAppChangeBottomNav الموجود في states.



class AppCubit extends Cubit<AppStates> {

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


  int currentIndex = 0;

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

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

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

}


تشغيل واستخدام bloc داخل ملف المشروع layout .


تشغيل واستخدام bloc داخل ملف المشروع layout .

الان ارجع الصفحة التي تقوم فيها بتعريف المتغيرات وتغيير حالة التطبيق وهنا قم بعمل تغيير لكل نقرة وتغييره الوضعيه الخاصها بها مثل الappbar عند النقر عليه قم بتغيير العنوان على حسب الindex وايضا الصفحات قم بتغيرها بحسب الindex واخيرا انزل الى bottomNavigationBar وقم بتغييرها الى changeIndex وهي الmethode التي تم إنشائها داخل cubit والمسؤوله عن تغيير حالة الbottomNavigationBar في الشاشة .



class Home_Screen extends StatelessWidget {

  late Database database;
  var scaffoldKey = GlobalKey<ScaffoldState>();
  var formKey = GlobalKey<FormState>();
  bool isBottomSheetShow = false;
  IconData iconDate = Icons.edit;
  var title_controller = TextEditingController();
  var time_controller = TextEditingController();
  var date_controller = TextEditingController();

  @override
  Widget build(BuildContext context) {

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

          });
          }

          } 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) {
          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) {
          isBottomSheetShow = false;

          });
          isBottomSheetShow = true;

          }
          },
          child: Icon(iconDate),
          ),

          bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.fixed,
          elevation: 100.0,
          currentIndex: def.currentIndex,
          onTap: (index) {
         def.changeIndex(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'),
          ],
          ),
          );
        },

      ),
    );
  }
  
  Future 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');

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

      });
    });
  }

  Future<List<Map>> getDataFromDB(database) async
  {
    return await database!.rawQuery('SELECT * FROM tasks');
  }
}


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


تعليقات