هذا الدرس التطبيقي حول الترميز هو جزء من دورة "أساسيات Android Kotlin". يمكنك تحقيق أقصى استفادة من هذه الدورة التدريبية إذا اتبعت ترتيب الخطوات في دروس البرمجة. يتم إدراج جميع الدروس التطبيقية حول الترميز الخاصة بالدورة التدريبية في الصفحة المقصودة للدروس التطبيقية حول الترميز في دورة Android Kotlin Fundamentals.
مقدمة
يلخّص هذا الدرس التطبيقي حول الترميز كيفية استخدام ViewModel والتقسيمات معًا لتنفيذ عملية التنقّل. تذكَّر أنّ الهدف هو وضع منطق وقت التنقّل في ViewModel، ولكن حدِّد المسارات في الأجزاء وملف التنقّل. لتحقيق هذا الهدف، يمكنك استخدام نماذج العرض والتقسيمات وLiveData والمراقبين.
ينتهي الدرس العملي بعرض طريقة ذكية لتتبُّع حالات الأزرار بأقل قدر من الرموز البرمجية، بحيث يتم تفعيل كل زرّ ويمكن النقر عليه فقط عندما يكون من المنطقي أن ينقر المستخدِم على هذا الزرّ.
ما يجب معرفته
يجب أن تكون على دراية بما يلي:
- إنشاء واجهة مستخدم أساسية باستخدام نشاط وقِطع وعناصر عرض
- التنقّل بين الأجزاء واستخدام
safeArgsلنقل البيانات بين الأجزاء - عرض النماذج وعوامل إنشاء النماذج وعمليات التحويل و
LiveDataوالمراقبين المرتبطين بها - كيفية إنشاء قاعدة بيانات
Roomوإنشاء عنصر الوصول إلى البيانات (DAO) وتحديد الكيانات - كيفية استخدام الروتينات الفرعية للتفاعلات مع قاعدة البيانات والمهام الأخرى التي تستغرق وقتًا طويلاً
أهداف الدورة التعليمية
- كيفية تعديل سجلّ حالي لجودة النوم في قاعدة البيانات
- كيفية استخدام
LiveDataلتتبُّع حالات الأزرار - كيفية عرض شريط معلومات استجابةً لحدث
الإجراءات التي ستنفذّها
- وسِّع تطبيق TrackMySleepQuality لجمع تقييم الجودة وإضافة التقييم إلى قاعدة البيانات وعرض النتيجة.
- استخدِم
LiveDataلتفعيل عرض شريط المعلومات. - استخدِم
LiveDataلتفعيل الأزرار وإيقافها.
في هذا الدرس البرمجي، ستنشئ واجهة المستخدم النهائية لتطبيق TrackMySleepQuality وتسجّل جودة النوم.
يحتوي التطبيق على شاشتَين، يتم تمثيلهما بلقطات، كما هو موضّح في الشكل أدناه.
تحتوي الشاشة الأولى، المعروضة على اليمين، على أزرار لبدء التتبُّع وإيقافه. تعرِض الشاشة جميع بيانات نوم المستخدم. يؤدي النقر على الزر محو إلى حذف جميع البيانات التي جمعها التطبيق للمستخدم نهائيًا.
الشاشة الثانية، المعروضة على اليسار، مخصّصة لاختيار تقييم لجودة النوم. في التطبيق، يتم تمثيل التقييم رقميًا. لأغراض التطوير، يعرض التطبيق رموز الوجوه وما يعادلها من أرقام.
يكون تدفّق المستخدم على النحو التالي:
- يفتح المستخدم التطبيق وتظهر له شاشة تتبُّع النوم.
- ينقر المستخدم على الزر بدء. تسجّل هذه السمة وقت البدء وتعرضه. يكون زر بدء غير مفعَّل، بينما يكون زر إيقاف مفعَّلاً.
- ينقر المستخدم على الزر إيقاف. يتم تسجيل وقت الانتهاء وفتح شاشة جودة النوم.
- يختار المستخدم رمزًا لجودة النوم. تنغلق الشاشة، وتعرض شاشة التتبُّع وقت انتهاء النوم وجودته. يكون زر إيقاف غير مفعَّل ويكون زر بدء مفعَّلاً. التطبيق جاهز للاستخدام في ليلة أخرى.
- يتم تفعيل الزر محو عندما تكون هناك بيانات في قاعدة البيانات. عندما ينقر المستخدم على الزر محو، يتم محو جميع بياناته بدون رجعة، ولن تظهر الرسالة "هل أنت متأكد؟".
يستخدم هذا التطبيق بنية مبسطة، كما هو موضّح أدناه في سياق البنية الكاملة. يستخدم التطبيق المكوّنات التالية فقط:
- وحدة التحكّم في واجهة المستخدم
- عرض النموذج و
LiveData - قاعدة بيانات Room
يفترض هذا الدرس التطبيقي حول الترميز أنّك تعرف كيفية تنفيذ التنقّل باستخدام الأجزاء وملف التنقّل. لتوفير الوقت، يتم توفير جزء كبير من هذا الرمز.
الخطوة 1: فحص الرمز
- للبدء، يمكنك مواصلة استخدام الرمز الخاص بك من نهاية آخر درس برمجة، أو تنزيل الرمز المُعد مسبقًا للمبتدئين.
- في رمز البداية، افحص
SleepQualityFragment. تعمل هذه الفئة على توسيع التصميم والحصول على التطبيق وعرضbinding.root. - افتح navigation.xml في "محرِّر التصميم". يمكنك ملاحظة مسار تنقّل من
SleepTrackerFragmentإلىSleepQualityFragment، ثم العودة منSleepQualityFragmentإلىSleepTrackerFragment.
- افحص الرمز بحثًا عن navigation.xml. على وجه الخصوص، ابحث عن
<argument>باسمsleepNightKey.
عندما ينتقل المستخدم منSleepTrackerFragmentإلىSleepQualityFragment,، سيمرِّر التطبيقsleepNightKeyإلىSleepQualityFragmentلليلة التي يجب تعديلها.
الخطوة 2: إضافة أزرار التنقّل لتتبُّع جودة النوم
يتضمّن الرسم البياني للتنقّل المسارات من SleepTrackerFragment إلى SleepQualityFragment والعودة مرة أخرى. ومع ذلك، لم تتم كتابة رموز معالجات النقرات التي تنفّذ عملية التنقّل من جزء إلى آخر بعد. يمكنك إضافة هذا الرمز الآن في ViewModel.
في معالج النقرات، يمكنك ضبط LiveData يتغيّر عندما تريد أن ينتقل التطبيق إلى وجهة مختلفة. تراقب الفئة Fragment هذا LiveData. عندما تتغيّر البيانات، ينتقل الجزء إلى الوجهة ويُعلم نموذج العرض بأنّه قد انتهى، ما يؤدي إلى إعادة ضبط متغيّر الحالة.
- فتح "
SleepTrackerViewModel" عليك إضافة أداة التنقّل حتى يتمكّن التطبيق من الانتقال إلىSleepQualityFragmentلجمع تقييم الجودة عندما ينقر المستخدم على الزر إيقاف. - في
SleepTrackerViewModel، أنشئLiveDataيتغيّر عندما تريد أن ينتقل التطبيق إلىSleepQualityFragment. استخدِم التغليف لعرض نسخة قابلة للاسترداد منLiveDataإلىViewModelفقط.
يمكنك وضع هذا الرمز في أي مكان في المستوى الأعلى من نص الصف.
private val _navigateToSleepQuality = MutableLiveData<SleepNight>()
val navigateToSleepQuality: LiveData<SleepNight>
get() = _navigateToSleepQuality- أضِف الدالة
doneNavigating()التي تعيد ضبط المتغيّر الذي يؤدي إلى التنقّل.
fun doneNavigating() {
_navigateToSleepQuality.value = null
}- في معالج النقر على الزر إيقاف،
onStopTracking()، ابدأ التنقّل إلىSleepQualityFragment. اضبط المتغيّر _navigateToSleepQualityفي نهاية الدالة كآخر عنصر داخل كتلةlaunch{}. يُرجى العِلم أنّه تم ضبط هذه السمة علىnight. عندما يتضمّن هذا المتغيّر قيمة، ينتقل التطبيق إلىSleepQualityFragment، مع تمرير الليلة.
_navigateToSleepQuality.value = oldNight- يجب أن يراقب
SleepTrackerFragment_navigateToSleepQualityلكي يعرف التطبيق متى يجب الانتقال إلى صفحة أخرى. فيSleepTrackerFragment، ضمنonCreateView()، أضِف مراقبًا إلىnavigateToSleepQuality(). يُرجى العِلم أنّ عملية الاستيراد هذه غير واضحة، وعليك استيرادandroidx.lifecycle.Observer.
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {
})
- داخل كتلة المراقب، انتقِل إلى رقم تعريف الليلة الحالية ومرِّره، ثم استدعِ
doneNavigating(). إذا كان الاستيراد غامضًا، استورِدandroidx.navigation.fragment.findNavController.
night ->
night?.let {
this.findNavController().navigate(
SleepTrackerFragmentDirections
.actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
sleepTrackerViewModel.doneNavigating()
}- أنشئ تطبيقك وشغِّله. انقر على بدء، ثم انقر على إيقاف، ما سينقلك إلى شاشة
SleepQualityFragment. للرجوع، استخدِم زر الرجوع في النظام.
في هذه المهمة، عليك تسجيل جودة النوم والرجوع إلى جزء أداة تتبُّع النوم. من المفترض أن يتم تعديل شاشة الميزان تلقائيًا لعرض القيمة المعدَّلة للمستخدم. عليك إنشاء ViewModel وViewModelFactory، كما عليك تعديل SleepQualityFragment.
الخطوة 1: إنشاء ViewModel وViewModelFactory
- في حزمة
sleepquality، أنشئ الملف SleepQualityViewModel.kt أو افتحه. - أنشئ فئة
SleepQualityViewModelتأخذsleepNightKeyوقاعدة بيانات كمعلَمات. كما فعلت معSleepTrackerViewModel، عليك تمريرdatabaseمن المصنع. يجب أيضًا تمريرsleepNightKeyمن التنقّل.
class SleepQualityViewModel(
private val sleepNightKey: Long = 0L,
val database: SleepDatabaseDao) : ViewModel() {
}- داخل الفئة
SleepQualityViewModel، حدِّدJobوuiScope، وألغِonCleared().
.
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}- للانتقال إلى
SleepTrackerFragmentباستخدام النمط نفسه المذكور أعلاه، عليك تعريف_navigateToSleepTracker. نفِّذ الترميزَينnavigateToSleepTrackerوdoneNavigating().
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()
val navigateToSleepTracker: LiveData<Boolean?>
get() = _navigateToSleepTracker
fun doneNavigating() {
_navigateToSleepTracker.value = null
}- أنشئ معالج نقرة واحدًا،
onSetSleepQuality()، لجميع صور جودة النوم التي تريد استخدامها.
استخدِم نمط الروتين الفرعي نفسه كما في الدرس العملي السابق:
- ابدأ روتينًا فرعيًا في
uiScope، ثم انتقِل إلى أداة توزيع عمليات الإدخال والإخراج. - يمكنك الحصول على
tonightباستخدامsleepNightKey. - اضبط جودة النوم.
- تعديل قاعدة البيانات
- بدء التنقّل
لاحظ أنّ نموذج الرمز البرمجي أدناه ينفّذ كل العمل في معالج النقرات، بدلاً من استبعاد عملية قاعدة البيانات في السياق المختلف.
fun onSetSleepQuality(quality: Int) {
uiScope.launch {
// IO is a thread pool for running operations that access the disk, such as
// our Room database.
withContext(Dispatchers.IO) {
val tonight = database.get(sleepNightKey) ?: return@withContext
tonight.sleepQuality = quality
database.update(tonight)
}
// Setting this state variable to true will alert the observer and trigger navigation.
_navigateToSleepTracker.value = true
}
}- في حزمة
sleepquality، أنشئSleepQualityViewModelFactory.ktأو افتحه وأضِف فئةSleepQualityViewModelFactory، كما هو موضّح أدناه. يستخدم هذا الصف إصدارًا من رمز النموذج نفسه الذي سبق أن رأيته. يُرجى فحص الرمز البرمجي قبل المتابعة.
class SleepQualityViewModelFactory(
private val sleepNightKey: Long,
private val dataSource: SleepDatabaseDao) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SleepQualityViewModel::class.java)) {
return SleepQualityViewModel(sleepNightKey, dataSource) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}الخطوة 2: تعديل SleepQualityFragment
- فتح "
SleepQualityFragment.kt" - في
onCreateView()، بعد الحصول علىapplication، عليك الحصول علىargumentsالذي تم تضمينه مع نظام الملاحة. تكون هذه الوسيطات فيSleepQualityFragmentArgs. عليك استخراجها من الحزمة.
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)- بعد ذلك، احصل على
dataSource.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao- أنشئ مصنعًا، مع إدخال
dataSourceوsleepNightKey.
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)- الحصول على مرجع
ViewModel
val sleepQualityViewModel =
ViewModelProviders.of(
this, viewModelFactory).get(SleepQualityViewModel::class.java)- أضِف
ViewModelإلى عنصر الربط. (إذا ظهر لك خطأ في عنصر الربط، تجاهله في الوقت الحالي).
binding.sleepQualityViewModel = sleepQualityViewModel- أضِف المراقب. عندما يُطلب منك ذلك، استورِد
androidx.lifecycle.Observer.
sleepQualityViewModel.navigateToSleepTracker.observe(this, Observer {
if (it == true) { // Observed state is true.
this.findNavController().navigate(
SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment())
sleepQualityViewModel.doneNavigating()
}
})الخطوة 3: تعديل ملف التصميم وتشغيل التطبيق
- افتح ملف التنسيق
fragment_sleep_quality.xml. في المربّع<data>، أضِف متغيّرًا لـSleepQualityViewModel.
<data>
<variable
name="sleepQualityViewModel"
type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
</data>- لكل صورة من صور جودة النوم الست، أضِف أداة معالجة نقرات مثل تلك الواردة أدناه. مطابقة تقييم الجودة مع الصورة
android:onClick="@{() -> sleepQualityViewModel.onSetSleepQuality(5)}"- نظِّف مشروعك وأعِد إنشاءه. من المفترض أن يحلّ ذلك أي أخطاء في عنصر الربط. بخلاف ذلك، امحِ ذاكرة التخزين المؤقت (ملف > إبطال ذاكرات التخزين المؤقت / إعادة التشغيل) وأعِد إنشاء تطبيقك.
تهانينا! لقد أنشأت للتو تطبيق قاعدة بيانات Room كاملاً باستخدام إجراءات فرعية.
أصبح تطبيقك يعمل بشكل رائع الآن. يمكن للمستخدم النقر على بدء وإيقاف عدة مرات كما يريد. عندما ينقر المستخدم على إيقاف، يمكنه إدخال جودة النوم. عندما ينقر المستخدم على محو، يتم محو جميع البيانات في الخلفية بدون إشعاره. ومع ذلك، تكون جميع الأزرار مفعّلة دائمًا ويمكن النقر عليها، ما لا يؤدي إلى تعطيل التطبيق، ولكنه يسمح للمستخدمين بإنشاء ليالٍ غير مكتملة من النوم.
في هذه المهمة الأخيرة، ستتعرّف على كيفية استخدام خرائط التحويل لإدارة إمكانية ظهور الأزرار حتى يتمكّن المستخدمون من اتّخاذ الخيار الصحيح فقط. يمكنك استخدام طريقة مشابهة لعرض رسالة ودّية بعد محو جميع البيانات.
الخطوة 1: تعديل حالات الأزرار
الفكرة هي ضبط حالة الزر بحيث يكون زر البدء فقط مفعّلاً في البداية، ما يعني أنّه يمكن النقر عليه.
بعد أن ينقر المستخدم على بدء، يتم تفعيل الزر إيقاف وإيقاف الزر بدء. لا يتم تفعيل الزر محو إلا عندما تكون هناك بيانات في قاعدة البيانات.
- افتح ملف التنسيق
fragment_sleep_tracker.xml. - أضِف السمة
android:enabledإلى كل زر. السمةandroid:enabledهي قيمة منطقية تشير إلى ما إذا كان الزر مفعّلاً أم لا. (يمكن النقر على الزر المفعَّل، ولكن لا يمكن النقر على الزر غير المفعَّل). امنح السمة قيمة متغيرة للحالة ستحدّدها بعد قليل.
start_button:
android:enabled="@{sleepTrackerViewModel.startButtonVisible}"stop_button:
android:enabled="@{sleepTrackerViewModel.stopButtonVisible}"clear_button:
android:enabled="@{sleepTrackerViewModel.clearButtonVisible}"- افتح
SleepTrackerViewModelوأنشئ ثلاثة متغيرات مقابلة. عيِّن لكل متغيّر عملية تحويل تختبره.
- يجب أن يكون زر بدء مفعَّلاً عندما تكون قيمة
tonightهيnull. - يجب تفعيل الزر إيقاف عندما لا تكون قيمة
tonightهيnull. - يجب تفعيل الزر محو فقط إذا كان
nights، وبالتالي قاعدة البيانات، يحتوي على ليالٍ من النوم.
val startButtonVisible = Transformations.map(tonight) {
it == null
}
val stopButtonVisible = Transformations.map(tonight) {
it != null
}
val clearButtonVisible = Transformations.map(nights) {
it?.isNotEmpty()
}- شغِّل تطبيقك وجرِّب الأزرار.
الخطوة 2: استخدام شريط إعلام منبثق لإعلام المستخدم
بعد أن يمحو المستخدم قاعدة البيانات، اعرض له تأكيدًا باستخدام الأداة Snackbar. يوفّر شريط الإعلام المنبثق ملاحظات موجزة حول عملية ما من خلال رسالة تظهر في أسفل الشاشة. يختفي شريط المعلومات بعد انتهاء المهلة أو بعد تفاعل المستخدم في مكان آخر على الشاشة أو بعد أن يمرّر المستخدم شريط المعلومات سريعًا خارج الشاشة.
عرض شريط المعلومات هو مهمة خاصة بواجهة المستخدم، ويجب أن يتم ذلك في الجزء. يتم تحديد ما إذا كان سيتم عرض شريط المعلومات في ViewModel. لإعداد شريط معلومات سريع وعرضه عند محو البيانات، يمكنك استخدام الأسلوب نفسه المستخدَم لعرض شريط التنقّل.
- في
SleepTrackerViewModel، أنشئ الحدث المغلف.
private var _showSnackbarEvent = MutableLiveData<Boolean>()
val showSnackBarEvent: LiveData<Boolean>
get() = _showSnackbarEvent- بعد ذلك، نفِّذ
doneShowingSnackbar().
fun doneShowingSnackbar() {
_showSnackbarEvent.value = false
}- في
SleepTrackerFragment، ضمنonCreateView()، أضِف مراقبًا باتّباع الخطوات التالية:
sleepTrackerViewModel.showSnackBarEvent.observe(this, Observer { })- داخل كتلة المراقب، اعرض شريط المعلومات وأعِد ضبط الحدث على الفور.
if (it == true) { // Observed state is true.
Snackbar.make(
activity!!.findViewById(android.R.id.content),
getString(R.string.cleared_message),
Snackbar.LENGTH_SHORT // How long to display the message.
).show()
sleepTrackerViewModel.doneShowingSnackbar()
}- في
SleepTrackerViewModel، شغِّل الحدث في الطريقةonClear(). لإجراء ذلك، اضبط قيمة الحدث علىtrueداخل الحظرlaunch:
_showSnackbarEvent.value = true- أنشئ تطبيقك وشغِّله.
مشروع "استوديو Android": TrackMySleepQualityFinal
إنّ تنفيذ ميزة تتبُّع جودة النوم في هذا التطبيق يشبه تشغيل مقطوعة موسيقية مألوفة بمفتاح موسيقي جديد. على الرغم من تغيُّر التفاصيل، يبقى النمط الأساسي لما فعلته في دروس سابقة من هذا الدرس كما هو. إنّ معرفة هذه الأنماط يجعل الترميز أسرع بكثير، لأنّه يمكنك إعادة استخدام الرمز من التطبيقات الحالية. في ما يلي بعض الأنماط المستخدَمة في هذه الدورة التدريبية حتى الآن:
- أنشئ
ViewModelوViewModelFactoryوأعِدّ مصدر بيانات. - بدء التنقّل لفصل الاهتمامات، ضَع معالج النقرات في نموذج العرض والتنقّل في الجزء.
- استخدِم التغليف مع
LiveDataلتتبُّع تغييرات الحالة والردّ عليها. - استخدام عمليات التحويل مع
LiveData - إنشاء قاعدة بيانات ذات مثيل واحد
- إعداد إجراءات روتينية لعمليات قاعدة البيانات
بدء التنقّل
يمكنك تحديد مسارات التنقّل المحتملة بين الأجزاء في ملف تنقّل. هناك بعض الطرق المختلفة لتفعيل التنقّل من جزء إلى آخر. ومن بينها:
- حدِّد معالِجات
onClickلتفعيل التنقّل إلى جزء وجهة. - بدلاً من ذلك، لتفعيل التنقّل من جزء إلى آخر، اتّبِع الخطوات التالية:
- حدِّد قيمة
LiveDataلتسجيل ما إذا كان يجب أن يحدث التنقّل. - ربط أداة مراقبة بقيمة
LiveData - بعد ذلك، تغيّر الشفرة هذه القيمة كلما كان من الضروري بدء التنقّل أو عند اكتماله.
ضبط السمة android:enabled
- يتم تحديد السمة
android:enabledفيTextViewويتم توريثها من خلال جميع الفئات الفرعية، بما في ذلكButton. - تحدّد السمة
android:enabledما إذا كانViewمفعَّلاً أم لا. يختلف معنى "مفعَّل" حسب الفئة الفرعية. على سبيل المثال، يمنع العنصرEditTextغير المفعَّل المستخدم من تعديل النص المضمّن، ويمنع العنصرButtonغير المفعَّل المستخدم من النقر على الزر. - السمة
enabledليست هي نفسها السمةvisibility. - يمكنك استخدام خرائط التحويل لضبط قيمة السمة
enabledللأزرار استنادًا إلى حالة عنصر أو متغيّر آخر.
في ما يلي نقاط أخرى يتناولها هذا الدرس التطبيقي حول الترميز:
- لتفعيل الإشعارات للمستخدم، يمكنك استخدام الأسلوب نفسه الذي تستخدمه لتفعيل التنقّل.
- يمكنك استخدام
Snackbarلإرسال إشعار إلى المستخدم.
دورة Udacity التدريبية:
مستندات مطوّري تطبيقات Android:
يسرد هذا القسم مهامًا منزلية محتملة للطلاب الذين يعملون على هذا الدرس التطبيقي العملي كجزء من دورة تدريبية يقودها مدرّب. على المعلّم تنفيذ ما يلي:
- حدِّد واجبًا منزليًا إذا لزم الأمر.
- توضيح كيفية إرسال الواجبات المنزلية للطلاب
- وضع درجات للواجبات المنزلية
يمكن للمدرّبين استخدام هذه الاقتراحات بالقدر الذي يريدونه، ويجب ألا يترددوا في تكليف الطلاب بأي واجبات منزلية أخرى يرونها مناسبة.
إذا كنت تعمل على هذا الدرس العملي بنفسك، يمكنك استخدام مهام الواجب المنزلي هذه لاختبار معلوماتك.
الإجابة عن هذه الأسئلة
السؤال 1
إحدى طرق السماح لتطبيقك بتفعيل التنقّل من جزء إلى آخر هي استخدام قيمة LiveData للإشارة إلى ما إذا كان سيتم تفعيل التنقّل أم لا.
ما هي خطوات استخدام قيمة LiveData، والتي تُسمى gotoBlueFragment، لتفعيل التنقّل من الجزء الأحمر إلى الجزء الأزرق؟ اختر كلّ الإجابات المنطبقة.
- في
ViewModel، حدِّد قيمةLiveDatagotoBlueFragment. - في
RedFragment، لاحظ قيمةgotoBlueFragment. نفِّذ الرمزobserve{}للانتقال إلىBlueFragmentعند الاقتضاء، ثم أعِد ضبط قيمةgotoBlueFragmentللإشارة إلى اكتمال عملية التنقّل. - تأكَّد من أنّ الرمز البرمجي يضبط المتغيّر
gotoBlueFragmentعلى القيمة التي تؤدي إلى التنقّل كلّما احتاج التطبيق إلى الانتقال منRedFragmentإلىBlueFragment. - تأكَّد من أنّ الرمز البرمجي يحدّد معالج
onClickللعنصرViewالذي ينقر عليه المستخدم للانتقال إلىBlueFragment، حيث يراقب معالجonClickالقيمةgoToBlueFragment.
السؤال 2
يمكنك تغيير ما إذا كان Button مفعَّلاً (يمكن النقر عليه) أو لا باستخدام LiveData. كيف يمكنك التأكّد من أنّ تطبيقك يغيّر الزر UpdateNumber على النحو التالي:
- يكون الزر مفعَّلاً إذا كانت قيمة
myNumberأكبر من 5. - لا يتم تفعيل الزر إذا كان
myNumberيساوي 5 أو أقل.
لنفترض أنّ التنسيق الذي يحتوي على الزر UpdateNumber يتضمّن المتغيّر <data> الخاص بـ NumbersViewModel كما هو موضّح هنا:
<data>
<variable
name="NumbersViewModel"
type="com.example.android.numbersapp.NumbersViewModel" />
</data>لنفترض أنّ معرّف الزرّ في ملف التصميم هو ما يلي:
android:id="@+id/update_number_button"
ما هي الإجراءات الأخرى التي عليك اتّخاذها؟ يُرجى اختيار جميع الإجابات المناسبة.
- في الفئة
NumbersViewModel، حدِّد المتغيّرLiveData،myNumber، الذي يمثّل الرقم. حدِّد أيضًا متغيّرًا يتم ضبط قيمته من خلال استدعاءTransform.map()على المتغيّرmyNumber، ما يؤدي إلى عرض قيمة منطقية تشير إلى ما إذا كان الرقم أكبر من 5 أم لا.
على وجه التحديد، فيViewModel، أضِف الرمز التالي:
val myNumber: LiveData<Int>
val enableUpdateNumberButton = Transformations.map(myNumber) {
myNumber > 5
}- في تنسيق XML، اضبط السمة
android:enabledللعنصرupdate_number_button buttonعلىNumberViewModel.enableUpdateNumbersButton.
android:enabled="@{NumbersViewModel.enableUpdateNumberButton}"- في
Fragmentالذي يستخدم الفئةNumbersViewModel، أضِف مراقبًا إلى السمةenabledللزر.
على وجه التحديد، فيFragment، أضِف الرمز التالي:
// Observer for the enabled attribute
viewModel.enabled.observe(this, Observer<Boolean> { isEnabled ->
myNumber > 5
})- في ملف التصميم، اضبط السمة
android:enabledللعنصرupdate_number_button buttonعلى"Observable".
انتقِل إلى الدرس التالي:
للحصول على روابط تؤدي إلى دروس تطبيقية أخرى في هذه الدورة التدريبية، اطّلِع على الصفحة المقصودة الخاصة بالدروس التطبيقية حول أساسيات Android Kotlin.