Android Kotlin Fundamentals 06.3: از LiveData برای کنترل وضعیت دکمه ها استفاده کنید

این کد لبه بخشی از دوره آموزشی Android Kotlin Fundamentals است. اگر به ترتیب روی کدها کار کنید، بیشترین ارزش را از این دوره خواهید گرفت. همه کدهای دوره در صفحه فرود کد لبه های کدهای Android Kotlin Fundamentals فهرست شده اند.

مقدمه

این لبه کد نحوه استفاده از ViewModel و قطعات را با هم برای پیاده سازی ناوبری خلاصه می کند. به یاد داشته باشید که هدف این است که منطق زمان حرکت را در ViewModel قرار دهید، اما مسیرها را در قطعات و فایل ناوبری تعریف کنید. برای دستیابی به این هدف، از مدل‌های مشاهده، قطعات، LiveData و مشاهده‌گرها استفاده می‌کنید.

نرم افزار Codelab با نشان دادن روشی هوشمندانه برای ردیابی وضعیت دکمه ها با حداقل کد به پایان می رسد، به طوری که هر دکمه تنها زمانی فعال و قابل کلیک است که برای کاربر منطقی باشد که روی آن دکمه ضربه بزند.

آنچه از قبل باید بدانید

باید با:

  • ساخت یک رابط کاربری اولیه (UI) با استفاده از یک فعالیت، قطعات و نماها.
  • پیمایش بین قطعات و استفاده از safeArgs برای انتقال داده ها بین قطعات.
  • مشاهده مدل‌ها، مشاهده کارخانه‌های مدل، تبدیل‌ها، و LiveData و ناظران آن‌ها.
  • نحوه ایجاد پایگاه داده Room ، ایجاد یک شی دسترسی به داده (DAO) و تعریف موجودیت ها.
  • نحوه استفاده از کوروتین ها برای تعاملات پایگاه داده و سایر کارهای طولانی مدت.

چیزی که یاد خواهید گرفت

  • چگونه یک رکورد با کیفیت خواب موجود در پایگاه داده را به روز کنیم.
  • نحوه استفاده از LiveData برای ردیابی وضعیت دکمه ها.
  • نحوه نمایش اسنک بار در پاسخ به یک رویداد.

کاری که خواهی کرد

  • برنامه TrackMySleepQuality را برای جمع آوری رتبه بندی کیفیت، اضافه کردن رتبه به پایگاه داده و نمایش نتیجه گسترش دهید.
  • از LiveData برای فعال کردن نمایش نوار اسنک استفاده کنید.
  • از LiveData برای فعال و غیرفعال کردن دکمه ها استفاده کنید.

در این لبه کد، ضبط با کیفیت خواب و رابط کاربری نهایی برنامه TrackMySleepQuality را ایجاد می کنید.

همانطور که در شکل زیر نشان داده شده است، برنامه دارای دو صفحه است که با قطعات نشان داده شده است.

اولین صفحه نمایش داده شده در سمت چپ دارای دکمه هایی برای شروع و توقف ردیابی است. صفحه نمایش تمام داده های خواب کاربر را نشان می دهد. دکمه Clear تمام داده هایی را که برنامه برای کاربر جمع آوری کرده است برای همیشه حذف می کند.

صفحه دوم که در سمت راست نشان داده شده است، برای انتخاب رتبه بندی کیفیت خواب است. در برنامه، امتیاز به صورت عددی نشان داده می شود. برای اهداف توسعه، برنامه هم نمادهای چهره و هم معادل های عددی آنها را نشان می دهد.

جریان کاربر به شرح زیر است:

  • کاربر برنامه را باز می کند و با صفحه ردیابی خواب نمایش داده می شود.
  • کاربر روی دکمه Start ضربه می زند. این زمان شروع را ثبت کرده و نمایش می دهد. دکمه Start غیرفعال است و دکمه Stop فعال است.
  • کاربر روی دکمه Stop ضربه می زند. این کار زمان پایان را ثبت می کند و صفحه با کیفیت خواب را باز می کند.
  • کاربر یک نماد کیفیت خواب را انتخاب می کند. صفحه بسته می شود و صفحه ردیابی زمان پایان خواب و کیفیت خواب را نشان می دهد. دکمه Stop غیرفعال و دکمه Start فعال است. برنامه برای یک شب دیگر آماده است.
  • هر زمان که داده ای در پایگاه داده وجود داشته باشد، دکمه Clear فعال می شود. هنگامی که کاربر روی دکمه Clear ضربه می‌زند، تمام داده‌های او بدون مراجعه پاک می‌شوند - "آیا مطمئن هستید؟" وجود ندارد. پیام

این برنامه از معماری ساده شده استفاده می کند، همانطور که در زیر در زمینه معماری کامل نشان داده شده است. این برنامه فقط از اجزای زیر استفاده می کند:

  • کنترلر رابط کاربری
  • مشاهده مدل و LiveData
  • پایگاه داده اتاق

این کد لبه فرض می کند که شما می دانید چگونه با استفاده از قطعات و فایل ناوبری، ناوبری را پیاده سازی کنید. برای صرفه جویی در کار، مقدار زیادی از این کد ارائه شده است.

مرحله 1: کد را بررسی کنید

  1. برای شروع، از انتهای آخرین کد لبه کد خود را ادامه دهید یا کد شروع را دانلود کنید.
  2. در کد شروع، SleepQualityFragment را بررسی کنید. این کلاس layout را افزایش می دهد، برنامه را دریافت می کند و binding.root را برمی گرداند.
  3. navigation.xml را در ویرایشگر طراحی باز کنید. مشاهده می کنید که یک مسیر پیمایش از SleepTrackerFragment به SleepQualityFragment و دوباره از SleepQualityFragment به SleepTrackerFragment وجود دارد.



  4. کد navigation.xml را بررسی کنید. به طور خاص، به دنبال <argument> با نام sleepNightKey .

    هنگامی که کاربر از SleepTrackerFragment به SleepQualityFragment, برنامه یک sleepNightKey را برای شبی که نیاز به به روز رسانی دارد به SleepQualityFragment ارسال می کند.

مرحله 2: برای ردیابی کیفیت خواب، ناوبری را اضافه کنید

نمودار ناوبری از قبل شامل مسیرهایی از SleepTrackerFragment به SleepQualityFragment و دوباره بازگشت است. با این حال، کنترل‌کننده‌های کلیک که پیمایش از یک قطعه به قطعه دیگر را اجرا می‌کنند، هنوز کدگذاری نشده‌اند. اکنون آن کد را در ViewModel اضافه می کنید.

در کنترل کننده کلیک، LiveData را تنظیم می کنید که وقتی می خواهید برنامه به مقصد دیگری حرکت کند تغییر می کند. قطعه این LiveData را مشاهده می کند. هنگامی که داده ها تغییر می کنند، قطعه به مقصد حرکت می کند و به مدل view می گوید که کار انجام شده است، که متغیر حالت را بازنشانی می کند.

  1. SleepTrackerViewModel را باز کنید. باید ناوبری را اضافه کنید تا زمانی که کاربر روی دکمه Stop ضربه می‌زند، برنامه به SleepQualityFragment هدایت شود تا رتبه‌بندی کیفیت را جمع‌آوری کند.
  2. در SleepTrackerViewModel ، یک LiveData ایجاد کنید که وقتی می‌خواهید برنامه به SleepQualityFragment حرکت کند، تغییر می‌کند. از کپسوله‌سازی استفاده کنید تا فقط نسخه‌ای از LiveData را در اختیار ViewModel قرار دهید.

    شما می توانید این کد را در هر نقطه از سطح بالای بدنه کلاس قرار دهید.
private val _navigateToSleepQuality = MutableLiveData<SleepNight>()

val navigateToSleepQuality: LiveData<SleepNight>
   get() = _navigateToSleepQuality
  1. یک doneNavigating() اضافه کنید که متغیری را که ناوبری را راه‌اندازی می‌کند بازنشانی می‌کند.
fun doneNavigating() {
   _navigateToSleepQuality.value = null
}
  1. در کنترل کننده کلیک برای دکمه Stop ، onStopTracking() ، پیمایش به SleepQualityFragment را راه اندازی کنید. متغیر _ navigateToSleepQuality را در انتهای تابع به عنوان آخرین چیز در بلوک launch{} تنظیم کنید. توجه داشته باشید که این متغیر روی night تنظیم شده است. وقتی این متغیر مقداری دارد، برنامه به SleepQualityFragment هدایت می‌شود و در طول شب می‌گذرد.
_navigateToSleepQuality.value = oldNight
  1. SleepTrackerFragment باید _ navigateToSleepQuality را رعایت کند تا برنامه بداند چه زمانی باید پیمایش کند. در SleepTrackerFragment ، در onCreateView() یک ناظر برای navigateToSleepQuality() اضافه کنید. توجه داشته باشید که واردات برای این مبهم است و باید androidx.lifecycle.Observer را وارد کنید.
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {
})

  1. در داخل بلوک مشاهده‌گر، شناسه شب جاری را پیمایش کرده و از آن عبور کنید و سپس doneNavigating() را فراخوانی کنید. اگر واردات شما مبهم است، androidx.navigation.fragment.findNavController را وارد کنید.
night ->
night?.let {
   this.findNavController().navigate(
           SleepTrackerFragmentDirections
                   .actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
   sleepTrackerViewModel.doneNavigating()
}
  1. اپلیکیشن خود را بسازید و اجرا کنید. روی Start ضربه بزنید، سپس روی Stop ضربه بزنید، که شما را به صفحه SleepQualityFragment می برد. برای بازگشت، از دکمه بازگشت سیستم استفاده کنید.

در این کار، کیفیت خواب را ضبط می‌کنید و به بخش ردیاب خواب برمی‌گردید. نمایشگر باید به طور خودکار به روز شود تا مقدار به روز شده را به کاربر نشان دهد. شما باید یک ViewModel و یک ViewModelFactory ایجاد کنید و باید SleepQualityFragment را به روز کنید.

مرحله 1: یک ViewModel و یک ViewModelFactory ایجاد کنید

  1. در بسته sleepquality ، SleepQualityViewModel.kt را ایجاد یا باز کنید.
  2. یک کلاس SleepQualityViewModel ایجاد کنید که یک sleepNightKey و پایگاه داده را به عنوان آرگومان می گیرد. همانطور که برای SleepTrackerViewModel انجام دادید، باید از کارخانه وارد database شوید. شما همچنین باید در sleepNightKey از ناوبری عبور کنید.
class SleepQualityViewModel(
       private val sleepNightKey: Long = 0L,
       val database: SleepDatabaseDao) : ViewModel() {
}
  1. در کلاس SleepQualityViewModel یک Job و uiScope تعریف کنید و onCleared() لغو کنید.
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)

override fun onCleared() {
   super.onCleared()
   viewModelJob.cancel()
}
  1. برای بازگشت به SleepTrackerFragment با استفاده از الگوی مشابه بالا، _navigateToSleepTracker را اعلام کنید. () navigateToSleepTracker و doneNavigating() پیاده سازی کنید.
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()

val navigateToSleepTracker: LiveData<Boolean?>
   get() = _navigateToSleepTracker

fun doneNavigating() {
   _navigateToSleepTracker.value = null
}
  1. یک کنترلر، onSetSleepQuality() برای استفاده از تمام تصاویر با کیفیت خواب ایجاد کنید.

    از همان الگوی کوروتین مانند در بخش کد قبلی استفاده کنید:
  • یک coroutine را در uiScope راه اندازی کنید و به توزیع کننده I/O بروید.
  • 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
        }
    }
  1. در بسته sleepquality ، SleepQualityViewModelFactory.kt را ایجاد یا باز کنید و کلاس 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 را به روز کنید

  1. SleepQualityFragment.kt باز کنید.
  2. در onCreateView() ، پس از دریافت application ، باید arguments هایی را که همراه با ناوبری آمده است، دریافت کنید. این آرگومان ها در SleepQualityFragmentArgs هستند. شما باید آنها را از بسته نرم افزاری استخراج کنید.
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)
  1. بعد، dataSource را دریافت کنید.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
  1. یک کارخانه ایجاد کنید و از dataSource و sleepNightKey .
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)
  1. یک مرجع ViewModel دریافت کنید.
val sleepQualityViewModel =
       ViewModelProviders.of(
               this, viewModelFactory).get(SleepQualityViewModel::class.java)
  1. ViewModel را به شی binding اضافه کنید. (اگر خطایی در مورد اتصال مشاهده کردید، فعلاً آن را نادیده بگیرید.)
binding.sleepQualityViewModel = sleepQualityViewModel
  1. ناظر را اضافه کنید. وقتی از شما خواسته شد، androidx.lifecycle.Observer وارد کنید.
sleepQualityViewModel.navigateToSleepTracker.observe(this, Observer {
   if (it == true) { // Observed state is true.
       this.findNavController().navigate(
               SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment())
       sleepQualityViewModel.doneNavigating()
   }
})

مرحله 3: فایل طرح بندی را به روز کنید و برنامه را اجرا کنید

  1. فایل طرح بندی fragment_sleep_quality.xml را باز کنید. در بلوک <data> ، یک متغیر برای SleepQualityViewModel اضافه کنید.
 <data>
       <variable
           name="sleepQualityViewModel"
           type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
   </data>
  1. برای هر یک از شش تصویر با کیفیت خواب، یک کنترل کننده کلیک مانند تصویر زیر اضافه کنید. رتبه بندی کیفیت را با تصویر مطابقت دهید.
android:onClick="@{() -> sleepQualityViewModel.onSetSleepQuality(5)}"
  1. پروژه خود را تمیز و بازسازی کنید. این باید هر گونه خطا را در مورد شیء binding حل کند. در غیر این صورت، کش را پاک کنید ( File > Invalidate Caches / Restart ) و برنامه خود را دوباره بسازید.

تبریک می گویم! شما به تازگی یک برنامه کامل پایگاه داده Room را با استفاده از کوروتین ها ساخته اید.

اکنون برنامه شما عالی کار می کند. کاربر می تواند هر چند بار که بخواهد روی Start و Stop ضربه بزند. وقتی کاربر روی Stop ضربه می‌زند، می‌تواند کیفیت خواب را وارد کند. وقتی کاربر روی Clear ضربه می‌زند، تمام داده‌ها در پس‌زمینه بی‌صدا پاک می‌شوند. با این حال، همه دکمه ها همیشه فعال و قابل کلیک هستند، که برنامه را خراب نمی کند، اما به کاربران اجازه می دهد تا شب های خواب ناقص ایجاد کنند.

در این آخرین کار، یاد می گیرید که چگونه از نقشه های تبدیل برای مدیریت دید دکمه ها استفاده کنید تا کاربران فقط بتوانند انتخاب درستی داشته باشند. می توانید از روش مشابهی برای نمایش یک پیام دوستانه پس از پاک شدن همه داده ها استفاده کنید.

مرحله 1: وضعیت های دکمه را به روز کنید

ایده این است که وضعیت دکمه را طوری تنظیم کنید که در ابتدا فقط دکمه Start فعال باشد، یعنی قابل کلیک کردن است.

پس از ضربه زدن کاربر به Start ، دکمه Stop فعال می شود و Start فعال نمی شود. دکمه Clear تنها زمانی فعال می شود که داده در پایگاه داده وجود داشته باشد.

  1. فایل طرح بندی fragment_sleep_tracker.xml را باز کنید.
  2. ویژگی android:enabled را به هر دکمه اضافه کنید. ویژگی android:enabled یک مقدار بولی است که نشان می دهد دکمه فعال است یا خیر. (روی یک دکمه فعال می توان ضربه زد، یک دکمه غیرفعال نمی تواند.) مقدار متغیر حالتی را که در یک لحظه تعریف می کنید به ویژگی بدهید.

start_button :

android:enabled="@{sleepTrackerViewModel.startButtonVisible}"

stop_button :

android:enabled="@{sleepTrackerViewModel.stopButtonVisible}"

clear_button :

android:enabled="@{sleepTrackerViewModel.clearButtonVisible}"
  1. SleepTrackerViewModel را باز کنید و سه متغیر مربوطه ایجاد کنید. به هر متغیر تبدیلی اختصاص دهید که آن را آزمایش کند.
  • هنگامی که tonight null است، دکمه شروع باید فعال شود.
  • دکمه Stop زمانی که tonight null نیست باید فعال شود.
  • دکمه Clear فقط در صورتی باید فعال شود که nights و در نتیجه پایگاه داده حاوی شب‌های خواب باشد.
val startButtonVisible = Transformations.map(tonight) {
   it == null
}
val stopButtonVisible = Transformations.map(tonight) {
   it != null
}
val clearButtonVisible = Transformations.map(nights) {
   it?.isNotEmpty()
}
  1. برنامه خود را اجرا کنید و با دکمه ها آزمایش کنید.

مرحله 2: از نوار اسنک برای اطلاع دادن به کاربر استفاده کنید

پس از اینکه کاربر پایگاه داده را پاک کرد، با استفاده از ویجت Snackbar تأییدیه ای را به کاربر نشان دهید. یک نوار اسنک بازخورد مختصری در مورد یک عملیات از طریق پیامی در پایین صفحه ارائه می دهد. یک نوار اسنک پس از مهلت زمانی، پس از تعامل کاربر در جای دیگری از صفحه، یا پس از اینکه کاربر نوار اسنک را از روی صفحه نمایش می‌کشد، ناپدید می‌شود.

نمایش نوار اسنک یک کار رابط کاربری است و باید در قطعه اتفاق بیفتد. تصمیم گیری برای نمایش نوار اسنک در ViewModel اتفاق می افتد. برای راه‌اندازی و راه‌اندازی نوار اسنک در زمانی که داده‌ها پاک می‌شوند، می‌توانید از همان تکنیکی که برای راه‌اندازی ناوبری استفاده می‌کنید، استفاده کنید.

  1. در SleepTrackerViewModel ، رویداد کپسوله شده را ایجاد کنید.
private var _showSnackbarEvent = MutableLiveData<Boolean>()

val showSnackBarEvent: LiveData<Boolean>
   get() = _showSnackbarEvent
  1. سپس doneShowingSnackbar() را پیاده سازی کنید.
fun doneShowingSnackbar() {
   _showSnackbarEvent.value = false
}
  1. در SleepTrackerFragment ، در onCreateView() یک مشاهدهگر اضافه کنید:
sleepTrackerViewModel.showSnackBarEvent.observe(this, Observer { })
  1. در داخل بلوک ناظر، نوار اسنک را نمایش دهید و بلافاصله رویداد را بازنشانی کنید.
   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()
   }
  1. در SleepTrackerViewModel ، رویداد را در onClear() راه اندازی کنید. برای انجام این کار، مقدار رویداد را در داخل بلوک launch روی true تنظیم کنید:
_showSnackbarEvent.value = true
  1. اپلیکیشن خود را بسازید و اجرا کنید!

پروژه اندروید استودیو: TrackMySleepQualityFinal

اجرای ردیابی کیفیت خواب در این برنامه مانند پخش یک قطعه موسیقی آشنا در یک کلید جدید است. در حالی که جزئیات تغییر می کند، الگوی اساسی کاری که در کدهای قبلی در این درس انجام دادید یکسان باقی می ماند. آگاهی از این الگوها کدنویسی را بسیار سریعتر می کند، زیرا می توانید از کدهای برنامه های موجود مجددا استفاده کنید. در اینجا برخی از الگوهای استفاده شده در این دوره تا کنون آورده شده است:

  • یک ViewModel و یک ViewModelFactory ایجاد کنید و یک منبع داده راه اندازی کنید.
  • راه اندازی ناوبری. برای جدا کردن نگرانی ها، کنترل کننده کلیک را در مدل view و ناوبری را در قطعه قرار دهید.
  • از کپسوله‌سازی با LiveData برای ردیابی و پاسخ به تغییرات حالت استفاده کنید.
  • از تبدیل ها با LiveData استفاده کنید.
  • یک پایگاه داده singleton ایجاد کنید.
  • کوروتین ها را برای عملیات پایگاه داده تنظیم کنید.

راه اندازی ناوبری

شما مسیرهای ناوبری ممکن را بین قطعات در یک فایل ناوبری تعریف می کنید. راه های مختلفی برای راه اندازی ناوبری از یک قطعه به قطعه دیگر وجود دارد. این شامل:

  • کنترل کننده های onClick را برای راه اندازی ناوبری به یک قطعه مقصد تعریف کنید.
  • همچنین، برای فعال کردن پیمایش از یک قطعه به قطعه دیگر:
  • مقدار LiveData را برای ضبط در صورت ناوبری تعریف کنید.
  • یک ناظر را به آن مقدار LiveData کنید.
  • سپس هر زمان که پیمایش باید راه اندازی شود یا کامل شود، کد شما آن مقدار را تغییر می دهد.

تنظیم ویژگی android:enabled

  • ویژگی android:enabled در TextView تعریف شده و توسط همه زیر کلاس‌ها از جمله Button به ارث می‌رسد.
  • مشخصه android:enabled تعیین می کند که View فعال باشد یا خیر. معنای "فعال" بر اساس زیر کلاس متفاوت است. به عنوان مثال، یک EditText غیرفعال مانع از ویرایش متن موجود توسط کاربر می شود و یک دکمه غیرفعال از ضربه زدن کاربر روی Button جلوگیری می کند.
  • ویژگی enabled ویژگی visibility یکسان نیست.
  • می‌توانید از نقشه‌های تبدیل برای تنظیم مقدار ویژگی enabled دکمه‌ها بر اساس وضعیت یک شی یا متغیر دیگر استفاده کنید.

سایر نکاتی که در این کد لبه پوشش داده شده است:

  • برای فعال کردن اعلان‌ها به کاربر، می‌توانید از همان تکنیکی که برای راه‌اندازی ناوبری استفاده می‌کنید استفاده کنید.
  • می توانید از Snackbar برای اطلاع دادن به کاربر استفاده کنید.

دوره بی ادبی:

مستندات توسعه دهنده اندروید:

این بخش، تکالیف احتمالی را برای دانش‌آموزانی که در این آزمایشگاه کد به عنوان بخشی از دوره‌ای که توسط یک مربی هدایت می‌شود، فهرست می‌کند. این وظیفه مربی است که موارد زیر را انجام دهد:

  • در صورت نیاز تکالیف را تعیین کنید.
  • نحوه ارسال تکالیف را با دانش آموزان در میان بگذارید.
  • تکالیف را درجه بندی کنید.

مربیان می‌توانند از این پیشنهادات به اندازه‌ای که می‌خواهند استفاده کنند، و باید با خیال راحت هر تکلیف دیگری را که فکر می‌کنند مناسب است به آنها اختصاص دهند.

اگر به تنهایی بر روی این کدها کار می کنید، از این تکالیف برای آزمایش دانش خود استفاده کنید.

یه این سوالات پاسخ دهید

سوال 1

یکی از راه‌های فعال کردن برنامه برای فعال کردن پیمایش از یک قطعه به قطعه دیگر، استفاده از یک مقدار LiveData برای نشان دادن اینکه آیا ناوبری را راه‌اندازی می‌کند یا نه.

مراحل استفاده از یک مقدار LiveData ، به نام gotoBlueFragment ، برای راه اندازی پیمایش از قطعه قرمز به قطعه آبی چیست؟ همه موارد اعمال شده را انتخاب کنید:

  • در ViewModel مقدار LiveData gotoBlueFragment را تعریف کنید.
  • در RedFragment ، مقدار gotoBlueFragment را مشاهده کنید. کد Observ observe{} را اجرا کنید تا در صورت لزوم به BlueFragment و سپس مقدار gotoBlueFragment را تنظیم مجدد کنید تا نشان دهد که پیمایش کامل شده است.
  • مطمئن شوید که کد شما متغیر gotoBlueFragment را روی مقداری تنظیم می‌کند که هر زمان که برنامه نیاز دارد از RedFragment به BlueFragment ، پیمایش را فعال می‌کند.
  • مطمئن شوید که کد شما یک کنترل کننده onClick را برای View تعریف می کند که کاربر برای رفتن به BlueFragment روی آن کلیک می کند، جایی که کنترل کننده onClick مقدار goToBlueFragment را مشاهده می کند.

سوال 2

با استفاده از LiveData می‌توانید فعال (قابل کلیک) بودن یک Button را تغییر دهید. چگونه مطمئن می شوید که برنامه شما دکمه UpdateNumber را تغییر می دهد تا:

  • اگر مقدار myNumber بیشتر از 5 باشد، دکمه فعال می شود.
  • اگر myNumber برابر یا کمتر از 5 باشد، دکمه فعال نمی شود.

فرض کنید که چیدمان حاوی دکمه UpdateNumber شامل متغیر <data> برای NumbersViewModel همانطور که در اینجا نشان داده شده است:

<data>
   <variable
       name="NumbersViewModel"
       type="com.example.android.numbersapp.NumbersViewModel" />
</data>

فرض کنید شناسه دکمه در فایل layout به صورت زیر باشد:

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
})
  • در فایل layout، ویژگی android:enabled update_number_button button را روی "Observable" تنظیم کنید.

شروع به درس بعدی: 7.1 اصول RecyclerView

برای پیوند به دیگر کدهای این دوره، به صفحه فرود کد لبه‌های کد پایه Android Kotlin Fundamentals مراجعه کنید.