ميزة التنقل المشروط في Android باستخدام تسجيل الدخول

يُعد هذا الدرس التطبيقي جزءًا من الدورة التدريبية المتقدّمة لنظام التشغيل Android في لغة Kotlin. ستحصل على أقصى استفادة من هذه الدورة التدريبية إذا كنت تعمل من خلال الدروس التطبيقية حول الترميز بالتسلسل، ولكن هذا ليس إلزاميًا. يتم إدراج جميع الدروس التطبيقية حول ترميز الدورات التدريبية في الصفحة المقصودة لبرنامج Android المتقدّم في لغة ترميز Kotlin.


يعتمد هذا الدرس التطبيقي على الترميز على تنفيذ تسجيل الدخول على Android باستخدام FirebaseUI. على الرغم من أنه يمكنك تنزيل الرمز البرمجي للمبتدئين لهذا الدرس التطبيقي في حال عدم تنفيذ الدرس التطبيقي السابق، قد يكون من المفيد إكمال الدرس التطبيقي حول تنفيذ تسجيل الدخول على Android باستخدام FirebaseUI.

مقدمة

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

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

في هذا الدرس التطبيقي حول الترميز، ستنشئ فوق تطبيق حالي لإضافة شاشة إعدادات لا يمكن للمستخدمين الوصول إليها إلا إذا سجّلوا الدخول. ستستخدم مكونات التنقل في Android في هذه المهمة.

ما يجب معرفته

ما ستتعرَّف عليه

  • كيفية التنقُّل بين المستخدمين على الشاشات المناسبة لتطبيقك استنادًا إلى ما إذا كانوا قد سجَّلوا الدخول أم لا.

الإجراءات التي ستنفذّها

  • تعامل بشكل صحيح مع تنقل المستخدمين إلى الشاشة الصحيحة بعد تسجيل الدخول بنجاح.
  • يمكنك منع المستخدمين من الوصول إلى شاشة الإعدادات إذا لم يسجّلوا الدخول، وإعادة توجيههم إلى شاشة تسجيل الدخول بدلاً من ذلك.

في الدرس التطبيقي السابق حول الترميز، عملت على تطبيق يعرض حقائق عن Android. وقد سمح تطبيقك أيضًا للمستخدمين بتسجيل الدخول والخروج. بالنسبة إلى هذا الدرس التطبيقي حول الترميز، عليك إضافة شاشة إعدادات إلى التطبيق الحالي. ولن يتمكن المستخدم من الوصول إلى شاشة الإعدادات إلا إذا سجّل الدخول.

إذا لم يكن المستخدم مسجّلاً الدخول، سيعيد التطبيق توجيهه إلى شاشة تسجيل الدخول عند محاولة الوصول إلى شاشة الإعدادات. بعد اكتمال عملية تسجيل الدخول بنجاح، سيُعيد المستخدم إلى شاشة الإعدادات التي حاول الوصول إليها في الأصل.

يعتمد هذا الدرس التطبيقي على تنفيذ تسجيل الدخول على Android باستخدام FirebaseUI. على الرغم من أنه يمكنك تنزيل الرمز البرمجي للمبتدئين لهذا الدرس التطبيقي في حال عدم تنفيذ الدرس التطبيقي السابق، قد يكون من المفيد إكمال الدرس التطبيقي حول تنفيذ تسجيل الدخول على Android باستخدام FirebaseUI.

يمكنك تنزيل نموذج التطبيق، ويمكنك تنفيذ أحد الإجراءين التاليَين:

تنزيل ملف Zip


... أو استنساخ مستودع GitHub من سطر الأوامر باستخدام الأمر التالي والتبديل إلى فرع start للقاعدة:

$  git clone https://github.com/googlecodelabs/android-kotlin-login-navigation

بعد تحميل المشروع في "استوديو Android":

  1. شغِّل التطبيق على المحاكي أو الجهاز الفعلي للتأكُّد من إعداد بيئتك بنجاح لبدء التطوير.

في حال النجاح، ستظهر الشاشة الرئيسية التي تعرض حقيقة ممتعة على Android وزر تسجيل دخول في أعلى اليمين.


الميزات الحالية في تطبيق إجراء التفعيل:

  • إذا لم يكن المستخدم مسجّلاً الدخول، يؤدي النقر على زر تسجيل الدخول إلى بدء مسار تسجيل الدخول ويسمح للمستخدم بتسجيل الدخول باستخدام عنوان بريد إلكتروني أو حساب Google.
  • إذا كان المستخدم مسجّلاً الدخول، يتغير الزر إلى زر تسجيل الخروج الذي يسمح للمستخدم بتسجيل الخروج.

في هذه المهمة، ستضيف زرًا على الشاشة الرئيسية يسمح للمستخدم بالانتقال إلى شاشة الإعدادات. تتيح شاشة الإعدادات للمستخدم اختيار نوع الحقائق الممتعة التي يريد عرضها على الشاشة الرئيسية. ومن شاشة الإعدادات، يمكن للمستخدمين إمّا اختيار الاطّلاع على حقائق حول نظام التشغيل Android أو حقائق عن ولاية كاليفورنيا.

  1. فتح fragment_main.xml
  2. في fragment_main.xml,، أضِف زر الإعدادات مدمجًا في ConstraintLayout، وضَعه في أعلى يسار الشاشة.

fragment_main.xml

<TextView
       android:id="@+id/settings_btn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_margin="@dimen/text_margin"
       android:background="@color/colorAccent"
       android:padding="10dp"
       android:text="@string/settings_btn"
       android:textColor="#ffffff"
       android:textSize="20sp"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintTop_toTopOf="parent"/>
  1. فتح nav_graph.xml
  2. إضافة إجراء داخل mainFragment. id للإجراء هو action_mainFragment_to_customizeFragment، والوجهة هي customizeFragment.

nav_graph.xml

<fragment
       android:id="@+id/mainFragment"
       android:name="com.example.android.firebaseui_login_sample.MainFragment"
       android:label="MainFragment">
   <action
           android:id="@+id/action_mainFragment_to_settingsFragment"
           app:destination="@id/settingsFragment"/>
</fragment>
  1. فتح MainFragment.kt
  2. في onViewCreated()، اضبط onClickListener على settings_btn، بحيث يؤدي النقر على الزر إلى توجيه المستخدم إلى customizeFragment.

MainFragment.kt

binding.settingsBtn.setOnClickListener {
   val action = MainFragmentDirections.actionMainFragmentToSettingsFragment()
   findNavController().navigate(action)
}
  1. إذا ظهرت لك أخطاء لم يتم حلها، يمكنك إعادة تجميع التطبيق من قائمة الإصدار لإنشاء إجراءات التنقل الجديدة التي أنشأتها واستخدامها.
  2. أعِد تشغيل التطبيق. من المفترض أن يظهر لك الآن زر إعدادات وظيفي في أعلى يسار الشاشة.
  3. انقر على الزر الذي من المفترض أن ينقلك إلى شاشة الإعدادات. تتضمن شاشة الإعدادات خيارًا واحدًا فقط، وذلك للسماح للمستخدم باختيار نوع الحقائق الممتعة التي يريد رؤيتها على الشاشة الرئيسية.
  4. انقر على زر الرجوع في جهاز Android للعودة إلى الشاشة الرئيسية.

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

  1. فتح SettingsFragment.kt
  2. في onViewCreated()، عليك ملاحظة authenticationState وإعادة توجيه المستخدم إلى LoginFragment إذا لم تتم مصادقته.

SettingsFragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
   super.onViewCreated(view, savedInstanceState)
   val navController = findNavController()
   viewModel.authenticationState.observe(viewLifecycleOwner, Observer { authenticationState ->
       when (authenticationState) {
           LoginViewModel.AuthenticationState.AUTHENTICATED -> Log.i(TAG, "Authenticated")
           // If the user is not logged in, they should not be able to set any preferences,
           // so navigate them to the login fragment
           LoginViewModel.AuthenticationState.UNAUTHENTICATED -> navController.navigate(
               R.id.loginFragment
           )
           else -> Log.e(
               TAG, "New $authenticationState state that doesn't require any UI change"
           )
       }
   })
}

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

  1. فتح LoginFragment.kt
  2. خلال onViewCreated()، يمكنك معالجة إجراءات زر الرجوع عن طريق إعادة المستخدم إلى MainFragment.

LoginFragment.kt

// If the user presses the back button, bring them back to the home screen
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
   navController.popBackStack(R.id.mainFragment, false)
}
  1. أعِد تشغيل تطبيقك وتأكَّد من أنّه إذا لم تكن مُسجَّل الدخول، ستؤدي محاولات الوصول إلى شاشة الإعدادات الآن إلى إعادة توجيهك إلى صفحة تسجيل الدخول.

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

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

ومع ذلك، بعد إكمال عملية تسجيل الدخول، يتم إعادتك إلى شاشة تسجيل الدخول مرة أخرى. لا يترك هذا انطباعًا جيدًا لدى المستخدم، وقد يسبب التباسًا.

لتقديم تجربة المستخدم المثالية، على التطبيق إعادة المستخدم إلى شاشة الإعدادات بعد تسجيل المستخدم الدخول بنجاح.

  1. في LoginFragment.kt'، في أي مكان في onViewCreated()، لاحظ authenticationState وانتقل إلى المستخدم مرة أخرى في SettingsFragment عند المصادقة بنجاح.

LoginFragment.kt

// Observe the authentication state so we can know if the user has logged in successfully.
// If the user has logged in successfully, bring them back to the settings screen.
// If the user did not log in successfully, display an error message.
viewModel.authenticationState.observe(viewLifecycleOwner, Observer { authenticationState ->
   when (authenticationState) {
      // Since our login flow is only one screen instead of multiple 
      // screens, we can utilize popBackStack(). If our login flow 
      // consisted of multiple screens, we would have to call 
      // popBackStack() multiple times.
       LoginViewModel.AuthenticationState.AUTHENTICATED -> navController.popBackStack()
       else -> Log.e(
           TAG,
           "Authentication state that doesn't require any UI change $authenticationState"
       )
   }
})
  1. شغِّل تطبيقك مرة أخرى وتأكد من أنه عند تسجيل الدخول بنجاح، ستنتقل إلى صفحة الإعدادات بدلاً من صفحة تسجيل الدخول.

يمكنك التحقق من التطبيق الكامل باستخدام كل رموز الحل في جهاز Github repo https://github.com/googlecodelabs/android-kotlin-login-Navigation.

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

لمزيد من المعلومات عن أفضل ممارسات التنقل في Android، راجع الموارد التالية:

مستندات مطوّر برامج Android:

الدروس التطبيقية حول الترميز:

للحصول على روابط إلى دروس تطبيقية أخرى حول الترميز في هذه الدورة التدريبية، اطّلِع على الصفحة المقصودة للإصدارات المتقدّمة من Android في لغة ترميز Kotlin.