إنشاء صفحة login مع استخدام الapi بواسطة flutter

إنشاء صفحة login مع استخدام الapi بواسطة flutter


إنشاء صفحة login مع استخدام الapi بواسطة flutter

في هذا الدرس سوف نتعرف بشكل اكبر على الapi وكيف نقوم بإنشاء كلاس مخصص لاستقبال البيانات والاضافه والحذف منها وايضا التعامل مع البيانات التي تحصل عليها من الapi وكيف تجعل التطبيق الخاص بك يفهمها وكيف يتم عرضها وكيف التعامل معها , كل ما عليك هو عمل class بإسم DioHelper وهو الذي تقوم بوضع الاكواد التي تريدها بداخله وحالات التعامل مع البيانات وهنا نريد التعامل مع get و post اي عرض واضافة بيانات ويمكنك ايضا التعامل مع الحذف عن طريق نفس الفكرة المستخدمة في الشرح .


ظهرت لغة دارت في سنة 2011 و فلاتر ظهر في سنة 2017 وهذا يعني انهاومن بيئات العمل الجديده وللمعلومية flutter من تطوير العملاق جوجل والتي تطور الكثير من اللغات وتهتم بعالم البرمجه بشكل كبير جدا وهي ايضا من قامت بتطوير كوتلن والمختصه بتطوير تطبيقات الاندرويد واصبحت المنافسه للجافا وذلك بعد المشاكل التي واجهتها جوجل بسبب التطبيقات المطوره باستخدام جافا على Google play واصبحت تقدم الكثير من libraries التي تسهل على المطورين العمل وتسهل عليهم الكثير من الوقت في انشاء وتطوير تطبيقات الجوال بشكل سريع .


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


كود التعامل مع روابط api

كود التعامل مع روابط api

هذا الكود هو DioHelper والذي سبق وتم شرحه مسبقا وبكل بساطة هو مخصص لتهيئة التعامل مع البيانات التي تحصل عليها من السيرفر وبهذا الclass تقوم بتجهيز نوعية البيانات سواء get , post , remove وتقوم بكتابة الاكواد المخصصه لكل نوع منها .



class DioHelper {
  static late Dio dio;

  static init() {
    dio = Dio(
      BaseOptions(
        receiveDataWhenStatusError: true,
        baseUrl: 'https://student.valuxapps.com/api/',
      ),
    );
  }

  static Future<Response> getData({
    required String url,
    Map<String, dynamic>? query,
    String lang = 'ar',
    String? token,
  }) async
  {
    return await dio.get(
      url,
      queryParameters: query,
    );
  }

  static Future<Response> postData({
    required String url,
    required Map<String, dynamic> data,
    Map<String, dynamic>? query,
    String lang = 'en',
    String? token,
  }) async
  {
    dio.options.headers =
    {
      'lang':lang,
      'Authorization': token??'',
      'Content-Type': 'application/json',
    };

    return dio.post(
      url,
      queryParameters: query,
      data: data,
    );
  }
}


الاكواد المستخدمه داخل ملف cubit


الاكواد المستخدمه داخل ملف cubit


هنا تقوم بتهيئة ملف للCubit وكما نعلم انه عليك عمل ملف states لكي لا يحدث معك مشاكل في ملف Cubit وبعدها عند استخدام الapi يحتاج منك الend point وهنا كانت login ولكن بدلا من كتابها قمنا بعمل ملف مخصص للend point لكي نقوم بكتابة جميع الروابط النهائيه للمشروع كما هو موضح وبعدها نستخدمها وتكمل الكود الخاص بك لو تلاحظ كان يطلب هنا الemail و password ولذلك لان هذه البيانات مطلوبه في الbody عند فحصها على الpostman .



class LoginCubit extends Cubit<LoginStates>{
  LoginCubit() : super(LoginInitialState());
  static LoginCubit get(context)=> BlocProvider.of(context);

  void userLogin({
    required String email,
    required String password,
  }) {
    emit(LoginLoadingState());
    DioHelper.postData(url: LOGIN, data: {
      'email':email,
      'password':password,
    }) .then((value){
      print(value.data);
      emit(LoginSuccessState());
    }).catchError((onError) {
      emit(LoginErrorState(onError.toString()));
    });
  }

  IconData suffix = Icons.visibility_rounded;
  bool isPasswordShow = true;

  void changePassword() {
    isPasswordShow = !isPasswordShow;
    suffix =
    isPasswordShow ? Icons.visibility_rounded : Icons.visibility_off_rounded;
    emit(LoginChangePasswordState());
  }
}

كود التصميم النهائي الخاص بصفحة تسجيل الدخول


كود التصميم النهائي الخاص بصفحة تسجيل الدخول


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



class LoginScreen extends StatelessWidget {
  LoginScreen({Key? key}) : super(key: key);
  var emailController = TextEditingController();
  var passwordController = TextEditingController();
  var formKey = GlobalKey<FormState>();


  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (BuildContext context) => LoginCubit(),
      child: BlocConsumer<LoginCubit , LoginStates>(
        listener: (context , states) {},
        builder: (context , states) {
          return Scaffold(
            body: Center(
              child: SingleChildScrollView(
                child: Padding(
                  padding: const EdgeInsets.all(25.0),
                  child: Form(
                    key: formKey,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
Text('Login' , style: Theme.of(context).textTheme.bodyText1!.copyWith(color: colorDefault, fontSize: 33),),
                        SizedBox(height: 10,),
                        defaultFormField(controller: emailController
                            ,
                            type: TextInputType.emailAddress,
                            validate: (String? value){
                              if (value!.isEmpty) {
                                return 'isEmpty';
                              }
                            },
                            label: 'label',
                            prefix: Icons.mail_rounded),
                        defaultFormField(controller: passwordController,
                            type: TextInputType.visiblePassword,
                            isPassword: LoginCubit.get(context).isPasswordShow,
                            suffixPressed: (){
                              LoginCubit.get(context).changePassword();
                            },
                            validate: (String? value){
                              if (value!.isEmpty) {
                                return 'isEmpty';
                              }
                            },
                            label: 'label',
                            // لجعل النقر على زر تم تنفيذ عملية زر الدخول بدلا من النقر عليها
                            onSubmit: (value){
                              if (formKey.currentState!.validate()) {
                                LoginCubit.get(context).userLogin(
                                  email: emailController.text,
                                  password: passwordController.text,
                                );
                              }
                            },

                            suffix: LoginCubit.get(context).suffix,
                            prefix: Icons.lock_outline_rounded),
                        SizedBox(height: 20,),
                        defaultTextButton(function: (){
                          navigateTo(context, RegisterScreen());
                        }, text: 'Don\'t Have an account ?'),
                        SizedBox(height: 20,),
                        BuildCondition(
                          condition: states is! LoginLoadingState,
                          builder: (context) => defaultButton(
                            function: () {
                              if (formKey.currentState!.validate()) {
                                LoginCubit.get(context).userLogin(
                                  email: emailController.text,
                                  password: passwordController.text,
                                );
                              }
                            },
                            text: 'login',
                            isUpperCase: true,
                          ),
                          fallback: (context) =>
                              Center(child: CircularProgressIndicator()),
                        ),

                      ],
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}


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

تعليقات