هذا الدرس التطبيقي حول الترميز هو جزء من دورة "أساسيات 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
، حدِّد قيمةLiveData
gotoBlueFragment
. - في
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.