Android Kotlin Fundamentals 05.2: LiveData ve LiveData Gözlemcileri

Bu codelab, Android Kotlin Temelleri kursuna dahildir. Codelab'ler üzerinden sırayla çalışıyorsanız bu kurstan en iyi şekilde yararlanabilirsiniz. Tüm kurs codelab'leri Android Kotlin Fundamentals codelabs açılış sayfasında listelenmektedir.

Giriş

Önceki codelab'de, GuessTheWord uygulamasında uygulama yapılandırmasının değişikliklerden kurtulması için bir ViewModel kullanıyordunuz. Bu codelab'de, LiveData ürününü ViewModel sınıflarındaki verilerle nasıl entegre edeceğinizi öğreneceksiniz. Android Architecture Components'tan biri olan LiveData, temel veritabanı değiştiğinde değişiklikleri bildiren veri nesneleri oluşturmanıza olanak tanır.

LiveData sınıfını kullanmak için uygulama verilerindeki değişiklikleri gözlemleyen "observers" (örneğin, etkinlikler veya parçalar) oluşturursunuz. LiveData yaşam döngüsüne duyarlıdır. Bu nedenle, yalnızca etkin yaşam döngüsü durumundaki uygulama bileşeni gözlemcilerini günceller.

Bilmeniz gerekenler

  • Kotlin'de temel Android uygulamaları oluşturma.
  • Uygulamanızın hedefleri arasında gezinme
  • Aktivite ve parça yaşam döngüsü.
  • Uygulamanızda ViewModel nesneleri nasıl kullanılır?
  • ViewModelProvider.Factory arayüzü kullanılarak ViewModel nesneleri oluşturma.

Neler öğreneceksiniz?

  • LiveData nesnesini yararlı kılan unsurlar.
  • ViewModel öğesinde depolanan verilere LiveData nasıl eklenir?
  • MutableLiveData ne zaman ve nasıl kullanılır?
  • LiveData. üzerindeki değişiklikleri gözlemlemek için gözlemci yöntemlerini ekleme
  • Bir destek özelliği kullanarak LiveData kapsülleme.
  • Kullanıcı arayüzü denetleyicisi ile karşılık gelen ViewModel arasında iletişim kurma.

Yapacaklarınız

  • Kelime ve GuessTheWord uygulamasında puan için LiveData kullanın.
  • Kelime veya puan değiştiğinde dikkat eden gözlemciler ekleyin.
  • Değiştirilen değerleri gösteren metin görünümlerini güncelleyin.
  • Oyunun tamamlandığı bir etkinlik eklemek için LiveData adlı gözlemcinin desenini kullanın.
  • Tekrar Oyna düğmesini uygulayın.

5. Ders codelab'lerinde ise GuessTheWord uygulamasını, başlangıç koduyla başlayabilirsiniz. GuessTheWord, oyuncuların mümkün olan en yüksek skoru elde etmek için işbirliği yaptığı iki kişilik karalar tarzı bir oyun.

İlk oyuncu uygulamadaki kelimelere bakar ve her birini sırayla uygulamaya koyar, kelimeyi ikinci oyuncuya göstermemeye dikkat eder. İkinci oyuncu kelimeyi tahmin etmeye çalışır.

İlk oyuncu, oyunu oynamak için cihazda uygulamayı açar ve aşağıdaki ekran görüntüsünde bulunan "gitar" gibi bir kelime görür.

İlk oyuncu, kelimeyi bilerek hareket etmemeye dikkat eder.

  • İkinci oyuncu kelimeyi doğru tahmin ettiğinde ilk oyuncu Anladım düğmesine basar ve sayıları bir artırır, ardından da gelen kelimeyi gösterir.
  • İkinci oyuncu kelimeyi tahmin edemezse ilk oyuncu Atla düğmesine basar, bu şekilde sayı bir azalır ve sonraki kelimeye atlanır.
  • Oyunu sonlandırmak için Oyunu Sonlandır düğmesine basın. (Bu işlev, serideki ilk codelab'in başlangıç kodunda yoktur.)

Bu codelab'de, kullanıcı uygulamadaki tüm kelimeleri çevirdiğinde oyunu sonlandırmak için GuessTheWord uygulamasını iyileştirdiniz. Ayrıca, puan parçasına Tekrar Oyna düğmesini ekleyerek kullanıcının oyunu tekrar oynayabilmesini sağlarsınız.

Başlık ekranı

Oyun ekranı

Skor ekranı

Bu görevde bu codelab için başlangıç kodunuzu bulup çalıştırırsınız. Başlangıç kodu olarak önceki codelab'de oluşturduğunuz GuessTheWord uygulamasını kullanabilir veya bir başlangıç uygulaması indirebilirsiniz.

  1. (İsteğe bağlı) Önceki codelab'den aldığınız kodu kullanmıyorsanız bu codelab için başlangıç kodunu indirin. Kodu arşivden çıkarıp projeyi Android Studio'da açın.
  2. Uygulamayı çalıştırıp oyunu oynayın.
  3. Atla düğmesinin sonraki kelimeyi gösterdiğini ve puanı bir oranında azalttığını ve Anladım düğmesinin sonraki kelimeyi gösterdiğini ve puanı bir birim artırdığını unutmayın. Oyunu Sonlandır düğmesi oyunu bitirir.

LiveData, yaşam döngüsüne duyarlı, gözlemlenebilir bir veri sahibi sınıfıdır. Örneğin, LiveData ifadesini GuessTheWord uygulamasında geçerli puanın etrafına sarabilirsiniz. Bu codelab'de LiveData özelliğinin çeşitli özellikleri hakkında bilgi edinirsiniz:

  • LiveData gözlemlenebilirdir. Diğer bir deyişle, LiveData nesnesinin barındırdığı veriler değiştiğinde bir gözlemciye bilgi verilir.
  • LiveData verileri saklar; LiveData tüm verilerle kullanılabilen bir sarmalayıcıdır
  • LiveData yaşam döngüsüne duyarlıdır. Yani yalnızca STARTED veya RESUMED gibi etkin bir yaşam döngüsü durumunda olan gözlemcileri günceller.

Bu görevde GameViewModel öğesindeki mevcut puanı ve geçerli kelime verilerini LiveData biçimine dönüştürerek herhangi bir veri türünü LiveData nesnelerine nasıl sarmalayacağınızı öğrenebilirsiniz. Daha sonraki bir görevde, bu LiveData nesnesine bir gözlemci ekler ve LiveData öğesinin nasıl gözlemleneceğini öğrenirsiniz.

1. Adım: LiveData'yı kullanmak için skoru ve kelimeyi değiştirin

  1. screens/game paketinin altında GameViewModel dosyasını açın.
  2. score ve word değişkenlerinin türünü MutableLiveData olarak değiştirin.

    MutableLiveData, değeri değiştirilebilir bir LiveData. MutableLiveData genel bir sınıftır. Bu nedenle, barındırdığı veri türünü belirtmeniz gerekir.
// The current word
val word = MutableLiveData<String>()
// The current score
val score = MutableLiveData<Int>()
  1. GameViewModel içinde, init bloğunun içinde score ve word öğesini başlatın. Bir LiveData değişkeninin değerini değiştirmek için değişkendeki setValue() yöntemini kullanırsınız. Kotlin'de value özelliğini kullanarak setValue() numaralı telefonu arayabilirsiniz.
init {

   word.value = ""
   score.value = 0
  ...
}

2. Adım: LiveData nesne referansını güncelleyin

score ve word değişkenleri artık LiveData türünde. Bu adımda, value özelliğini kullanarak bu değişkenlere yapılan referansları değiştirirsiniz.

  1. GameViewModel ürününde onSkip() yönteminde, score değerini score.value olarak değiştirin. score ürününün null olma olasılığı hakkındaki hataya dikkat edin. Daha sonra bu hatayı düzeltirsiniz.
  2. Hatayı düzeltmek için onSkip() konumundaki score.value adresine null kontrolü ekleyin. Sonra, score üzerinde minus() işlevini çağırın. Bu işlev, null güvenliğiyle çıkarma işlemini gerçekleştirir.
fun onSkip() {
   if (!wordList.isEmpty()) {
       score.value = (score.value)?.minus(1)
   }
   nextWord()
}
  1. onCorrect() yöntemini aynı şekilde güncelleyin: score değişkenine bir null kontrolü ekleyin ve plus() işlevini kullanın.
fun onCorrect() {
   if (!wordList.isEmpty()) {
       score.value = (score.value)?.plus(1)
   }
   nextWord()
}
  1. GameViewModel içinde, nextWord() yönteminin içindeki word referansını word.value olarak değiştirin.
private fun nextWord() {
   if (!wordList.isEmpty()) {
       //Select and remove a word from the list
       word.value = wordList.removeAt(0)
   }
}
  1. GameFragment içinde, updateWordText() yönteminin içindeki referansı viewModel.word olarak viewModel.word.value. olarak değiştirin
/** Methods for updating the UI **/
private fun updateWordText() {
   binding.wordText.text = viewModel.word.value
}
  1. GameFragment içinde, updateScoreText() yönteminin içindeki viewModel.score referansını viewModel.score.value. olarak değiştirin
private fun updateScoreText() {
   binding.scoreText.text = viewModel.score.value.toString()
}
  1. GameFragment içinde, gameFinished() yönteminin içindeki referansı viewModel.score olarak viewModel.score.value olarak değiştirin. Gerekli null güvenlik kontrolünü ekleyin.
private fun gameFinished() {
   Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
   val action = GameFragmentDirections.actionGameToScore()
   action.score = viewModel.score.value?:0
   NavHostFragment.findNavController(this).navigate(action)
}
  1. Kodunuzda hata olmadığından emin olun. Uygulamanızı derleyip çalıştırın. Uygulamanın işlevselliği öncekiyle aynı olmalıdır.

Bu görev, puan ve kelime verilerini LiveData nesnelerine dönüştürdüğünüz önceki görevle yakından ilgilidir. Bu görevde bu LiveData nesnelerine Observer nesneleri eklersiniz.

  1. onCreateView() yöntemindeki GameFragment, içinde, mevcut puan (viewModel.score) için LiveData nesnesine bir Observer nesnesi ekleyin. observe() yöntemini kullanın ve kodu, viewModel ilk kullanıma hazırlandıktan sonra yerleştirin. Kodu basitleştirmek için bir lambda ifadesi kullanın. (lambda ifadesi, bildirilmemiş anonim bir işlevdir, ancak hemen bir ifade olarak aktarılır.)
viewModel.score.observe(this, Observer { newScore ->
})

Observer referansını çözün. Bunu yapmak için Observer simgesini tıklayın, Alt+Enter (Mac'te Option+Enter) tuşuna basın ve androidx.lifecycle.Observer içe aktarın.

  1. Yeni oluşturduğunuz gözlemci, gözlemlenen LiveData nesnesinin barındırdığı veriler değiştiğinde bir etkinlik alır. Gözlemcinin içinde, TextView skorunu yeni puanla güncelleyin.
/** Setting up LiveData observation relationship **/
viewModel.score.observe(this, Observer { newScore ->
   binding.scoreText.text = newScore.toString()
})
  1. Mevcut kelime LiveData nesnesine bir Observer nesnesi ekleyin. Geçerli puana Observer nesnesi ekler gibi yapın.
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
   binding.wordText.text = newWord
})

score veya word değeri değiştiğinde, ekranda görüntülenen score veya word artık otomatik olarak güncellenir.

  1. GameFragment ürününde updateWordText() ve updateScoreText() yöntemlerini ve bunlara tüm referansları silin. Metin görünümleri LiveData gözlemci yöntemleri tarafından güncellendiğinden artık buna ihtiyacınız yoktur.
  2. Uygulamanızı çalıştırın. Oyun uygulamanız daha önce olduğu gibi çalışmalıdır ancak artık LiveData ve LiveData gözlemcilerini kullanıyor.

Kapsülleme, bazı nesne alanlarına doğrudan erişimi kısıtlamanın bir yoludur. Bir nesneyi kapsüllediğinizde, gizli dahili alanları değiştiren bir dizi herkese açık yöntem görürsünüz. Kapsüllemeyi kullanarak diğer sınıfların bu dahili alanları nasıl işleyeceğini kontrol edebilirsiniz.

Mevcut kodunuzdaki herhangi bir harici sınıf, score özelliğini (örneğin, viewModel.score.value kullanarak) değiştirebilir. Bu codelab'de geliştirmekte olduğunuz uygulamada önemli olmayabilir, ancak üretim uygulamasında ViewModel nesnelerindeki verilerin kontrolüne sahip olmak istersiniz.

Uygulamanızdaki verileri yalnızca ViewModel düzenlemelidir. Ancak kullanıcı arayüzü denetleyicilerinin verileri okuması gerekir. Böylece veri alanları tamamen gizli olamaz. Uygulamanızın verilerini kapsüllemek için hem MutableLiveData hem de LiveData nesnelerini kullanırsınız.

MutableLiveData - LiveData:

  • MutableLiveData nesnesindeki veriler, adın ima edildiği şekilde değiştirilebilir. ViewModel içinde, verilerin MutableLiveData olması için düzenlenebilir olması gerekir.
  • LiveData nesnesindeki veriler okunabilir, ancak değiştirilemez. ViewModel dışından veriler okunabilir ancak düzenlenemez olmalıdır. Bu nedenle veriler LiveData olarak gösterilmelidir.

Bu stratejiyi uygulamak için Kotlin yedek mülkü kullanırsınız. Destek özelliği, tam nesne dışında bir alıcıdan sonuç döndürmenizi sağlar. Bu görevde, GuessTheWord uygulamasında score ve word nesneleri için bir yedekleme özelliği uyguluyorsunuz.

Puan ve kelime için bir destek özelliği ekleyin

  1. GameViewModel içinde, geçerli score nesnesini private yapın.
  2. Yedekleme özelliklerinde kullanılan adlandırma kuralını uygulamak için score politikasını _score olarak değiştirin. _score özelliği artık oyun puanının değiştirilebilir versiyonudur ve dahili olarak kullanılabilecektir.
  3. LiveData türünün score adlı herkese açık bir sürümünü oluşturun.
// The current score
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
  1. Başlatma hatası görüntüleniyor. Bu hata, GameFragment içinde score bir LiveData referansı olduğu ve score artık kendi seter'ına erişemediği için oluşur. Kotlin'deki alıcı ve ayarlar hakkında daha fazla bilgi edinmek için Alıcı ve Ayarlayıcılar bölümüne bakın.

    Hatayı çözmek için GameViewModel ürününde score nesnesinin get() yöntemini geçersiz kılın ve destek özelliği _score'yı döndürün.
val score: LiveData<Int>
   get() = _score
  1. GameViewModel içinde, score referansını dahili dahili _score sürümü olarak değiştirin.
init {
   ...
   _score.value = 0
   ...
}

...
fun onSkip() {
   if (!wordList.isEmpty()) {
       _score.value = (score.value)?.minus(1)
   }
  ...
}

fun onCorrect() {
   if (!wordList.isEmpty()) {
       _score.value = (score.value)?.plus(1)
   }
   ...
}
  1. word nesnesini _word nesnesi olarak yeniden adlandırın ve onun için bir destek özelliği ekleyin (score nesnesinde yaptığınız gibi).
// The current word
private val _word = MutableLiveData<String>()
val word: LiveData<String>
   get() = _word
...
init {
   _word.value = ""
   ...
}
...
private fun nextWord() {
   if (!wordList.isEmpty()) {
       //Select and remove a word from the list
       _word.value = wordList.removeAt(0)
   }
}

Tebrikler. word ve score LiveData nesnesini kapsüllediniz.

Kullanıcı Oyunu Sonlandır düğmesine dokunduğunda, geçerli uygulamanız puan ekranına gider. Ayrıca, oyuncular tüm kelimeleri çevirdiğinde uygulamanın puan ekranına gitmesini de istersiniz. Oyuncular son kelimeyi kullanarak bitirdikten sonra, kullanıcının düğmeye dokunmasına gerek kalmadan oyunun otomatik olarak sona ermesini istersiniz.

Bu işlevi uygulamak için tüm kelimeler gösterildiğinde bir etkinliğin tetiklenmesi ve ViewModel bölümünden parçaya iletilmesi gerekir. Bunu yapmak için LiveData gözlemleyici kalıbını kullanarak oyunda tamamlanan bir etkinliği modellemelisiniz.

Gözlemci kalıbı

Observer deseni bir yazılım tasarımı kalıbıdır. Nesneler arasındaki iletişimi belirtir: gözlemlenebilir ("gözlem &konusu") ve gözlemler. Gözlemlenebilir bir durum, gözlemleyicileri durumlarındaki değişiklikler hakkında bilgilendirir.

Bu uygulamada LiveData örneğinde, gözlemlenebilir (konu) LiveData nesnesidir ve gözlemleyiciler de kullanıcı arayüzü denetleyicilerindeki parçalar gibi yöntemlerdir. LiveData içinde sarmalanan veriler her değiştiğinde durum değişikliği gerçekleşir. LiveData sınıfları, ViewModel ile parça arasında iletişim kurma açısından çok önemlidir.

1. Adım: Oyun bitmiş etkinliği algılamak için LiveData'yı kullanma

Bu görevde oyunun tamamlandığı bir etkinliği modellemek için LiveData gözlemleyici desenini kullanırsınız.

  1. GameViewModel ürününde _eventGameFinish adlı bir Boolean MutableLiveData nesnesi oluşturun. Bu nesne, oyun sona eren etkinliği bekleyecektir.
  2. _eventGameFinish nesnesini başlattıktan sonra eventGameFinish adlı bir yedekleme özelliği başlatın ve başlatın.
// Event which triggers the end of the game
private val _eventGameFinish = MutableLiveData<Boolean>()
val eventGameFinish: LiveData<Boolean>
   get() = _eventGameFinish
  1. GameViewModel içinde bir onGameFinish() yöntemi ekleyin. Bu yöntemde, oyun bitmiş eventGameFinish etkinliğini true olarak ayarlayın.
/** Method for the game completed event **/
fun onGameFinish() {
   _eventGameFinish.value = true
}
  1. GameViewModel listesinde, kelime yönteminin boş olduğu durumlarda nextWord() yönteminde oyunu sonlandırın.
private fun nextWord() {
   if (wordList.isEmpty()) {
       onGameFinish()
   } else {
       //Select and remove a _word from the list
       _word.value = wordList.removeAt(0)
   }
}
  1. GameFragment içinde, onCreateView() içinde, viewModel başlatıldıktan sonra eventGameFinish için bir gözlemleyici ekleyin. observe() yöntemini kullanın. Lambda işlevinin içinde gameFinished() yöntemini çağırın.
// Observer for the Game finished event
viewModel.eventGameFinish.observe(this, Observer<Boolean> { hasFinished ->
   if (hasFinished) gameFinished()
})
  1. Uygulamanızı çalıştırın, oyunu oynayın ve tüm kelimeleri gözden geçirin. Siz Oyunu Sonlandır'a dokunana kadar uygulama, oyun parçasında kalmak yerine otomatik olarak puan ekranına gider.

    Kelime listesi boş olduktan sonra eventGameFinish ayarlanır, oyun parçasındaki ilişkili gözlemci yöntemi çağrılır ve uygulama, ekran parçasına gider.
  2. Eklediğiniz kodda yaşam döngüsü sorunu oluştu. Sorunu anlamak için GameFragment sınıfındaki gameFinished() kodunda gezinme kodunu yorumlayın. Toast mesajını yöntemde sakladığınızdan emin olun.
private fun gameFinished() {
       Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
//        val action = GameFragmentDirections.actionGameToScore()
//        action.score = viewModel.score.value?:0
//        NavHostFragment.findNavController(this).navigate(action)
   }
  1. Uygulamanızı çalıştırın, oyunu oynayın ve tüm kelimeleri gözden geçirin. Oyun ekranının alt kısmında kısa süreliğine "Oyun bitti" yazan bir kısa mesaj görünür. Bu, beklenen davranıştır.

Şimdi cihazı veya emülatörü döndürün. Kadeh tekrar görüntülenir! Cihazı birkaç kez daha döndürün, muhtemelen her seferinde kademesi görürsünüz. Bu bir hatadır çünkü kısa oyun oyun sona erdiğinde yalnızca bir kez gösterilir. Ekmek, parça her yeniden oluşturulduğunda görüntülenmemelidir. Bu sorunu bir sonraki görevde çözeceksiniz.

2. Adım: Oyun bitmiş etkinliği sıfırlayın

LiveData, gözlemcilere genellikle yalnızca veri değiştiğinde güncelleme gönderir. Bu davranışın istisnası, gözlemlenen kullanıcının etkin olmama durumu yerine etkin duruma geçmesiyle ilgili güncellemeler alır.

Bu nedenle, oyunda tamamlanan kadeh kaldırma işlemi uygulamanızda tekrar tekrar tetiklenir. Oyun parçası, ekran döndürmeden sonra yeniden oluşturulduğunda etkin değil durumundan etkin durumuna geçer. Parçadaki gözlemci, mevcut ViewModel öğesine yeniden bağlanır ve geçerli verileri alır. gameFinished() yöntemi yeniden tetiklenir ve kısa ileti gösterilir.

Bu görevde bu sorunu düzeltip kadehin yalnızca bir kez gösterilmesi için GameViewModel içindeki eventGameFinish işaretini sıfırlayın.

  1. GameViewModel oyununda _eventGameFinish adlı oyunun bitmiş etkinliğini sıfırlamak için bir onGameFinishComplete() yöntemi ekleyin.
/** Method for the game completed event **/

fun onGameFinishComplete() {
   _eventGameFinish.value = false
}
  1. GameFragment içinde, gameFinished() öğesinin sonunda, viewModel nesnesinde onGameFinishComplete() çağrısı yapın. (gameFinished() içindeki gezinme kodunu şimdilik yorum olarak bırakın.)
private fun gameFinished() {
   ...
   viewModel.onGameFinishComplete()
}
  1. Uygulamayı çalıştırıp oyunu oynayın. Tüm kelimeleri gözden geçirip cihazın ekran yönünü değiştirin. Durum mesajı yalnızca bir kez görüntülenir.
  2. GameFragment içinde, gameFinished() yönteminin içindeki gezinme kodunun açıklamasını kaldırın.

    Android Studio'da yorumunu kaldırmak için yorum yapılan satırları seçin ve Control+/ tuşuna (Mac'te Command+/) basın.
private fun gameFinished() {
   Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
   val action = GameFragmentDirections.actionGameToScore()
   action.score = viewModel.score.value?:0
   findNavController(this).navigate(action)
   viewModel.onGameFinishComplete()
}

Android Studio tarafından istenirse androidx.navigation.fragment.NavHostFragment.findNavController içe aktarın.

  1. Uygulamayı çalıştırıp oyunu oynayın. Tüm kelimeleri inceledikten sonra, uygulamanın nihai puan ekranına otomatik olarak gittiğinden emin olun.

Mükemmel! Uygulamanız, kelime listesinin boş olduğunu GameViewModel bölümünden oyun parçasına bildirmek amacıyla oyun bitmiş bir etkinliği tetiklemek için LiveData özelliğini kullanır. Daha sonra, oyun parçası puan parçasına gider.

Bu görevde puanı ScoreViewModel içinde bir LiveData nesnesi olarak değiştirir ve nesneye gözlemci eklersiniz. Bu görev, GameViewModel klasörüne LiveData eklediğinizde yaptığınız işleme benzer.

Bu değişiklikleri eksiksiz olması için ScoreViewModel üzerinde yapıyorsunuz. Böylece uygulamanızdaki tüm veriler LiveData özelliğini kullanır.

  1. ScoreViewModel içinde score değişken türünü MutableLiveData olarak değiştirin. Bunu, kural olarak _score olarak yeniden adlandırıp bir destek özelliği ekleyin.
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
   get() = _score
  1. ScoreViewModel içinde, init bloğunun içinde _score simgesini başlatın. init blokundaki günlüğü istediğiniz gibi kaldırabilir veya bırakabilirsiniz.
init {
   _score.value = finalScore
}
  1. ScoreFragment içinde, onCreateView() içinde, viewModel öğesini başlattıktan sonra LiveData puanı için bir gözlemci ekleyin. Lambda ifadesinin içinde, puan değerini puan metni görünümüne ayarlayın. Puan değeriyle metin görünümünü doğrudan atayan kodu ViewModel öğesinden kaldırın.

Eklenecek kod:

// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
   binding.scoreText.text = newScore.toString()
})

Kaldırılacak kod:

binding.scoreText.text = viewModel.score.toString()

Android Studio tarafından istendiğinde androidx.lifecycle.Observer içe aktarın.

  1. Uygulamanızı çalıştırıp oynayın. Uygulama daha önce olduğu gibi çalışıyor ancak şimdi skoru güncellemek için LiveData ve bir gözlemci kullanıyor.

Bu görevde puan ekranına Tekrar Oynat düğmesi ekler ve LiveData etkinliği kullanarak tıklama işleyicisini uygularsınız. Düğme, puan ekranından oyun ekranına gitmek için bir etkinliği tetikler.

Uygulamanın başlangıç kodu Tekrar Oyna düğmesini içerir, ancak düğme gizlidir.

  1. res/layout/score_fragment.xml ürününde play_again_button düğmesi için visibility özelliğinin değerini visible olarak değiştirin.
<Button
   android:id="@+id/play_again_button"
...
   android:visibility="visible"
 />
  1. ScoreViewModel içinde, _eventPlayAgain adlı bir Boolean tutmak için bir LiveData nesnesi ekleyin. Bu nesne, puan ekranından oyun ekranına gitmek için LiveData etkinliğini kaydetmek için kullanılır.
private val _eventPlayAgain = MutableLiveData<Boolean>()
val eventPlayAgain: LiveData<Boolean>
   get() = _eventPlayAgain
  1. ScoreViewModel ürününde _eventPlayAgain etkinliğini ayarlama ve sıfırlama yöntemlerini tanımlayın.
fun onPlayAgain() {
   _eventPlayAgain.value = true
}
fun onPlayAgainComplete() {
   _eventPlayAgain.value = false
}
  1. ScoreFragment için eventPlayAgain için bir gözlemci ekleyin. Kodu, onCreateView() ifadesinden sonra, return ifadesinin önüne koyun. Lambda ifadesinde oyun ekranına geri dönüp eventPlayAgain öğesini sıfırlayın.
// Navigates back to game when button is pressed
viewModel.eventPlayAgain.observe(this, Observer { playAgain ->
   if (playAgain) {
      findNavController().navigate(ScoreFragmentDirections.actionRestart())
       viewModel.onPlayAgainComplete()
   }
})

Android Studio tarafından istendiğinde androidx.navigation.fragment.findNavController içe aktarın.

  1. ScoreFragment içinde, onCreateView() içinde, PlayAgain düğmesine bir tıklama dinleyici ekleyin ve viewModel.onPlayAgain() işlevini arayın.
binding.playAgainButton.setOnClickListener {  viewModel.onPlayAgain()  }
  1. Uygulamanızı çalıştırıp oynayın. Oyun sona erdiğinde, puan ekranında son puanı ve Tekrar Oyna düğmesini görürsünüz. PlayAgain düğmesine dokunduktan sonra uygulama tekrar oynayabilmek için oyun ekranına gider.

Harika! Uygulamanızın mimarisini LiveDataViewModel içindeki nesneleri kullanacak şekilde değiştirdiniz ve gözlemcileri LiveData nesnelerine eklediniz. LiveData LiveData tarafından tutulan değer değiştiğinde, gözlemleyici nesnelerini bilgilendirir.

Android Studio projesi: GuessTheWord

LiveData

  • LiveData, Android Mimari Bileşenleri'nden biri olan ve yaşam döngüsüne duyarlı bir gözlemlenebilir veri sahibi sınıfıdır.
  • Veriler güncellendiğinde kullanıcı arayüzünün otomatik olarak güncellenmesini sağlamak için LiveData kullanabilirsiniz.
  • LiveData gözlemlenebilirdir. Bu, LiveData nesnesinin barındırdığı veriler değiştiğinde bir etkinlik veya parça gibi bir gözlemcinin bilgilendirilebileceği anlamına gelir.
  • LiveData verileri saklar. Tüm verilerle kullanılabilen bir sarmalayıcıdır.
  • LiveData yaşam döngüsüne duyarlıdır. Yani yalnızca STARTED veya RESUMED gibi etkin bir yaşam döngüsü durumunda olan gözlemcileri günceller.

LiveData eklemek için

  • ViewModel içindeki veri değişkenlerinin türünü LiveData veya MutableLiveData olarak değiştirin.

MutableLiveData, değeri değiştirilebilen bir LiveData nesnesidir. MutableLiveData genel bir sınıftır. Bu nedenle, barındırdığı veri türünü belirtmeniz gerekir.

  • LiveData tarafından tutulan verilerin değerini değiştirmek için LiveData değişkeninde setValue() yöntemini kullanın.

LiveData'yı kapsama

  • ViewModel içindeki LiveData düzenlenebilir olmalıdır. ViewModel dışında LiveData okunaklı olmalıdır. Bu durum bir Kotlin yedek mülkü kullanılarak uygulanabilir.
  • Kotlin yedekleme özelliği, alıcıdan tam nesne dışındaki bir şeyi döndürmenizi sağlar.
  • LiveData öğesini kapsüllemek için ViewModel içinde private MutableLiveData kullanın ve ViewModel dışında bir LiveData destek mülkü döndürün.

Gözlemlenebilir Canlı Veriler

  • LiveData bir gözlemleyici kalıbını izler. "Gözlemlenebilir"LiveData nesnesidir ve gözlemciler, kullanıcı arayüzü denetleyicilerindeki parçalar gibi yöntemlerdir. LiveData içinde sarmalanan veriler her değiştiğinde kullanıcı arayüzü denetleyicilerindeki gözlemci yöntemleri bilgilendirilir.
  • LiveData öğesini gözlemlenebilir hale getirmek için observe() yöntemini kullanarak gözlemcilerdeki LiveData referansına (etkinlikler ve parçalar gibi) bir gözlemleyici nesnesi ekleyin.
  • Bu LiveData gözlemleyici deseni, ViewModel aracılığıyla kullanıcı arayüzü denetleyicilerine iletişim kurmak için kullanılabilir.

Udacity kursu:

Android geliştirici dokümanları:

Diğer:

Bu bölümde, bir eğitmen tarafından sunulan kurs kapsamında bu codelab üzerinden çalışan öğrenciler için olası ev ödevi ödevleri listelenmektedir. Öğretmenin şunları yapması gerekir:

  • Gerekirse ev ödevini atayın.
  • Öğrencilere ev ödevlerinin nasıl gönderileceğini bildirin.
  • Ev ödevlerine not verin.

Öğretmenler bu önerileri istedikleri kadar kullanabilir veya uygun görebilir ve uygun olan diğer ev ödevlerini atayabilirler.

Bu codelab'de kendiniz çalışıyorsanız, bilginizi test etmek için bu ödevlerden yararlanabilirsiniz.

Bu soruları yanıtlayın

1. Soru

Harici nesnelerin verileri güncelleyemeden okuyabilmesi için bir ViewModel içinde depolanan LiveData öğesini nasıl kapsül edersiniz?

  • ViewModel nesnesinin içinde verilerin veri türünü private LiveData olarak değiştirin. MutableLiveData türündeki salt okunur verileri göstermek için bir yedekleme özelliği kullanın.
  • ViewModel nesnesinin içinde verilerin veri türünü private MutableLiveData olarak değiştirin. LiveData türündeki salt okunur verileri göstermek için bir yedekleme özelliği kullanın.
  • Kullanıcı arayüzü denetleyicisinde, verilerin veri türünü private MutableLiveData olarak değiştirin. LiveData türündeki salt okunur verileri göstermek için bir yedekleme özelliği kullanın.
  • ViewModel nesnesinin içinde verilerin veri türünü LiveData olarak değiştirin. LiveData türündeki salt okunur verileri göstermek için bir yedekleme özelliği kullanın.

2. Soru

Kullanıcı arayüzü denetleyicisi aşağıdaki durumlardan hangisindeyse LiveData bir kullanıcı arayüzü denetleyicisini (bir parça gibi) günceller?

  • Devam ettirdi
  • Arka planda
  • Duraklatıldı
  • Durduruldu

3. Soru

LiveData gözlemleyici deseninde gözlemlenebilir öğe nedir (gözlemlenen)?

  • Gözlemci yöntemi
  • LiveData nesnesindeki veriler
  • Kullanıcı arayüzü denetleyicisi
  • ViewModel nesnesi

Sonraki dersi başlatma: 5.3: ViewModel ve LiveData ile veri bağlama

Bu kurstaki diğer codelab'lerin bağlantılarına ulaşmak için Android Kotlin Fundamentals codelabs açılış sayfasına göz atın.