Lab Lab זה הוא חלק מקורס Android Kotlin Fundamentals. כדי להפיק את המקסימום מהקורס הזה, יש לפעול ברצף לפי קודי שיעור ה-Lab. כל שיעורי Lab של הקורסים מופיעים בדף הנחיתה של Lab Kotlin Fundamentals ל-Android Lab.
מבוא
ב-Codelab הזה אנחנו מסבירים איך להשתמש בקטעי קוד ViewModel
ובמקטעים יחד כדי להטמיע ניווט. חשוב לזכור שהיעד הוא להזין את הלוגיקה של מתי כדי לנווט אל הViewModel
, אבל להגדיר את הנתיבים במקטעים ( (fragments) ואת קובץ הניווט. כדי להשיג את המטרה הזו, צריך להשתמש במודלי צפייה, מקטעים, LiveData
וצופים.
מעבדת הקוד מסתיימת על ידי הצגת דרך חכמה לעקוב אחר מצבי הלחצן באמצעות קוד מינימלי, כך שכל לחצן יהיה מופעל וניתן ללחיצה רק כאשר יהיה הגיוני למשתמש להקיש על הלחצן הזה.
דברים שחשוב לדעת
כדאי שתכירו את:
- בניית ממשק משתמש בסיסי (UI) באמצעות פעילות, שברים וצפיות.
- מעבר בין מקטעים ושימוש ב-
safeArgs
כדי להעביר נתונים בין מקטעים. - הצגה של מודלים, הצגה של מפעלי מודלים, טרנספורמציות ו
LiveData
ושל הבודקים שלהם. - איך ליצור מסד נתונים מסוג
Room
, ליצור אובייקט גישה לנתונים (DAO) ולהגדיר ישויות. - איך להשתמש בשגרות באינטראקציות במסד נתונים ובמשימות ארוכות אחרות.
מה תלמדו
- איך לעדכן רשומה קיימת של איכות השינה במסד הנתונים.
- איך להשתמש ב-
LiveData
למעקב אחר מצבי לחצנים. - איך להציג מזנון בתגובה לאירוע?
הפעולות שתבצעו:
- מרחיבים את האפליקציה TrackMySleepquality כדי לאסוף דירוג איכות, מוסיפים את הדירוג למסד הנתונים ומציגים את התוצאה.
- שימוש ב-
LiveData
כדי להפעיל את התצוגה של מזנון. - יש להשתמש ב
LiveData
כדי להפעיל ולהשבית לחצנים.
ב-Codelab הזה, תיצרו הקלטה באיכות השינה וממשק המשתמש הסופי של אפליקציית MyMySleepquality.
לאפליקציה יש שני מסכים, המיוצגים על ידי מקטעים, כפי שמוצג באיור למטה.
במסך הראשון, שנמצא מימין, יש לחצנים להפעלה ולהפסקה של המעקב. במסך מוצגים כל נתוני השינה של המשתמש. לחצן הניקוי מוחק באופן סופי את כל הנתונים שהאפליקציה אספה עבור המשתמש.
המסך השני, שמוצג בצד שמאל, הוא בחירה בדירוג של איכות השינה. באפליקציה, הדירוג מיוצג באופן מספרי. למטרות פיתוח, האפליקציה מציגה גם את סמלי הפנים ואת הסמלים המספריים שלהם.
התהליך של המשתמש הוא:
- המשתמש פותח את האפליקציה ומוצג לו מסך מעקב אחר השינה.
- המשתמש מקיש על הלחצן התחלה. פעולה זו מתעדת את שעת ההתחלה ומציגה אותה. הלחצן התחלה מושבת, והלחצן עצירה מופעל.
- המשתמש מקיש על הלחצן עצירה. פעולה זו מתעדת את שעת הסיום ופותחים את מסך איכות השינה.
- המשתמש בוחר בסמל של איכות השינה. המסך נסגר, ובמסך המעקב מוצגות שעת הסיום ואיכות השינה. הלחצן עצירה מושבת והלחצן התחלה מופעל. האפליקציה מוכנה ללילה אחר.
- הלחצן ניקוי מופעל בכל פעם שיש נתונים במסד הנתונים. כשהמשתמש מקיש על הלחצן ניקוי, כל הנתונים שלו נמחקים ללא צורך בפעולה נוספת. אין הודעה "האם אתה בטוח?"
האפליקציה הזו משתמשת בארכיטקטורה פשוטה, כפי שמפורט בהמשך בהקשר של הארכיטקטורה המלאה. האפליקציה משתמשת רק ברכיבים הבאים:
- בקר ממשק משתמש
- הצגת הדגם ו-
LiveData
- מסד נתונים של חדר
ב-Codelab הזה אנחנו מניחים שאתם יודעים איך להטמיע ניווט בעזרת מקטעים (breaksnippet) וקובץ ניווט. כדי לחסוך לך עבודה, מסופק חלק גדול מהקוד הזה.
שלב 1: בודקים את הקוד
- כדי להתחיל, צריך להמשיך להזין את הקוד בסיום סוף שיעור ה-Lab האחרון או להוריד את הקוד למתחילים.
- בקוד למתחילים, בודקים את
SleepQualityFragment
. כיתה זו מנפחת את הפריסה, מקבלת את האפליקציה ומחזירה אתbinding.root
. - פותחים את Navigation.xml בעורך העיצוב. רואים שיש מסלול ניווט מ
SleepTrackerFragment
אלSleepQualityFragment
, ואז חזרה מSleepQualityFragment
לSleepTrackerFragment
. - יש לבדוק את הקוד של Navigation.xml. באופן ספציפי, יש לחפש את
<argument>
בשםsleepNightKey
.
כשהמשתמש עובר מ-SleepTrackerFragment
אלSleepQualityFragment,
, האפליקציה תעבירsleepNightKey
אלSleepQualityFragment
למשך הלילה שיש לעדכן.
שלב 2: הוספת ניווט למעקב אחר איכות השינה
תרשים הניווט כבר כולל את הנתיבים מ-SleepTrackerFragment
אל SleepQualityFragment
וחזרה. עם זאת, ה-handlers של הקליקים שמטמיעים את הניווט מקטע אחד לקטע הבא לא עוברים עדיין קוד. את הקוד הזה מוסיפים עכשיו בViewModel
.
ב-handler של הקליקים, מגדירים LiveData
שמשתנה כשהאפליקציה צריכה לנווט ליעד אחר. קטע הקוד מציין את 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
}
- ב-handler של הלחצן Stop, לוחצים על
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 תצורה
- בחבילה של
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
}
- אפשר ליצור handler אחד של קליק,
onSetSleepQuality()
, כדי להשתמש בכל התמונות באיכות שינה.
יש להשתמש באותו דפוס קורטיון כמו בדוגמת הקוד הקודמת:
- פותחים שגרת המשך ב-
uiScope
ועוברים לסדרן I/O. - אפשר לקבל את
tonight
באמצעות הsleepNightKey
. - מגדירים את איכות השינה.
- מעדכנים את מסד הנתונים.
- הפעלת הניווט.
הערה: דוגמת הקוד שמוצגת בהמשך מבצעת את כל הפעולות ב-handler של הקליקים, במקום לשקלל את פעולת מסד הנתונים בהקשר האחר.
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>
- עבור כל אחת משש התמונות באיכות שינה, יש להוסיף handler של קליק כמו זה שלמטה. להתאים את דירוג האיכות לתמונה.
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 Studio: TrackMySleepqualityFinal
הטמעה של מעקב אחר איכות השינה באפליקציה הזו היא כמו הפעלת קטע מוזיקה מוכר במפתח חדש. למרות שהפרטים משתנים, דפוס הבסיס של הפעולות שביצעתם במעבדות קוד קודמות בשיעור זה אינו משתנה. מודעות לדפוסים האלה מהירות הרבה יותר, כי אפשר לעשות שימוש חוזר בקוד מאפליקציות קיימות. לפניכם כמה מהדפוסים שהיו לקורס עד כה:
- יש ליצור
ViewModel
וViewModelFactory
ולהגדיר מקור נתונים. - הפעלת הניווט. כדי להפריד בין חששות, יש למקם את הגורם המטפל בקליקים במודל התצוגה ואת הניווט בשבר.
- כדי לעקוב אחר שינויים במדינה ולהגיב אליה, יש להשתמש באותיות רישיות עם
LiveData
. - שימוש בטרנספורמציות עם
LiveData
. - יוצרים מסד נתונים של Singleton.
- הגדרת שגרים לפעולות מסדי נתונים.
ניווט מופעל
אתם מגדירים נתיבי ניווט אפשריים בין מקטעים בקובץ ניווט. יש כמה דרכים להפעיל ניווט מקטע אחד לקטע הבא. רשימת המדינות כוללת את:
- יש להגדיר גורמי handler מסוג
onClick
כדי להפעיל ניווט למקטע יעד. - לחלופין, כדי לאפשר ניווט מקטע אחד לקטע הבא:
- יש להגדיר ערך
LiveData
לתיעוד אם הניווט יתבצע. - יש לצרף צופה לערך
LiveData
זה. - הקוד משנה את הערך הזה בכל פעם שיש להפעיל את הניווט או לסיים אותו.
הגדרת המאפיין android:Enabled
- המאפיין
android:enabled
מוגדר ב-TextView
בירושה על ידי כל כיתות המשנה, כוללButton
. - המאפיין
android:enabled
קובע אם הערךView
יופעל. המשמעות של "Enabled" משתנה לפי סיווג משנה. לדוגמה, אם המדיניותEditText
לא מופעלת, המשתמש לא יכול לערוך את הטקסט שכלול בה, ופרמטרButton
שלא מופעל מונע מהמשתמש להקיש על הלחצן. - המאפיין
enabled
אינו זהה למאפייןvisibility
. - ניתן להשתמש במפות טרנספורמציה כדי להגדיר את הערך של המאפיין
enabled
של לחצנים בהתאם למצב של אובייקט או משתנה אחר.
נקודות נוספות שחלות על Lab Lab זה:
- כדי להפעיל את ההתראות למשתמשים, אפשר להשתמש באותה שיטה שבה משתמשים כדי להפעיל את הניווט.
- אפשר להשתמש ב
Snackbar
כדי להודיע למשתמש.
קורס אוניברסיטה:
התיעוד של מפתח Android:
בקטע הזה מפורטות מטלות שיעורי בית אפשריות לתלמידים שעובדים עם קוד Lab הזה, במסגרת קורס בהדרכת מורה. למורה יש אפשרות לבצע את הפעולות הבאות:
- אם צריך, מקצים שיעורי בית.
- ספרו לתלמידים איך מגישים מטלות בשיעורי בית.
- לתת ציונים למטלות שיעורי הבית.
המורים יכולים להשתמש בהצעות האלה כמה שפחות, ומומלץ להקצות להן כל שיעורי בית שדעתם מתאימה להם.
אם אתם עובדים בעצמכם על שיעור הקוד הזה, אתם מוזמנים להשתמש במטלות שיעורי הבית האלה כדי לבחון את הידע שלכם.
מענה על השאלות האלה
שאלה 1
דרך אחת להפעיל את האפליקציה כדי להפעיל ניווט מקטע אחד לקטע הבא, היא להשתמש בערך LiveData
כדי לציין אם להפעיל או לא לנווט.
מהם השלבים לשימוש בערך LiveData
, שנקרא gotoBlueFragment
, כדי להפעיל ניווט מהמקטע האדום למקטע הכחול? יש לבחור בכל האפשרויות המתאימות:
- ב
ViewModel
, מגדירים את הערךLiveData
gotoBlueFragment
. - ב
RedFragment
, יש לשים לב לערךgotoBlueFragment
. יש ליישם את הקודobserve{}
כדי לנווט אלBlueFragment
במקרה הצורך, ולאחר מכן לאפס את הערך שלgotoBlueFragment
כדי לציין שהניווט הושלם. - יש לוודא שהקוד מגדיר את המשתנה
gotoBlueFragment
לערך שמפעיל את הניווט בכל פעם שהאפליקציה צריכה לעבור מ-RedFragment
ל-BlueFragment
. - יש לוודא שהקוד מגדיר handler של
onClick
עבורView
שעליו המשתמש לוחץ כדי לנווט אלBlueFragment
, כאשר ה-handler של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 Fundamentals Codelabs.