Bu codelab, Android Kotlin Hakkında Temel Bilgiler kursunun bir parçasıdır. Bu kurstan en iyi şekilde yararlanmak için codelab'leri sırayla tamamlamanızı öneririz. Kursla ilgili tüm codelab'ler Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında listelenir.
Giriş
Önceki codelab'de, bir web hizmetinden nasıl veri alacağınızı ve yanıtı nasıl ayrıştırarak veri nesnesine dönüştüreceğinizi öğrendiniz. Bu codelab'de, web URL'sindeki fotoğrafları yüklemek ve görüntülemek için bu bilgileri kullanacaksınız. Ayrıca, RecyclerView oluşturma ve bunu genel bakış sayfasında bir resim ızgarası görüntülemek için kullanma konusunu da tekrar ele alacaksınız.
Bilmeniz gerekenler
- Parçacık oluşturma ve kullanma
- Görünüm modelleri, görünüm modeli fabrikaları, dönüşümler ve
LiveDatadahil olmak üzere mimari bileşenleri kullanma - Retrofit ve Moshi kitaplıklarını kullanarak bir REST web hizmetinden JSON'ı nasıl alacağınızı ve bu verileri Kotlin nesnelerine nasıl ayrıştıracağınızı öğrenin.
RecyclerViewile ızgara düzeni oluşturmaAdapter,ViewHolderveDiffUtilnasıl çalışır?
Neler öğreneceksiniz?
- Web URL'sindeki bir resmi yüklemek ve görüntülemek için Glide kitaplığı nasıl kullanılır?
- Resim tablosu görüntülemek için
RecyclerViewve ızgara adaptörü kullanma - Resimler indirilirken ve görüntülenirken olası hataların nasıl ele alınacağı.
Yapacaklarınız
- MarsRealEstate uygulamasını, Mars mülk verilerinden resim URL'sini alacak ve bu resmi yükleyip görüntülemek için Glide'ı kullanacak şekilde değiştirin.
- Uygulamaya yükleme animasyonu ve hata simgesi ekleyin.
- Mars'taki tesislerin resimlerinden oluşan bir ızgara göstermek için
RecyclerViewkullanın. RecyclerViewöğesine durum ve hata işleme ekleyin.
Bu codelab'de (ve ilgili codelab'lerde) MarsRealEstate adlı bir uygulamayla çalışacaksınız. Bu uygulama, Mars'ta satılık mülkleri gösterir. Uygulama, fiyat ve mülkün satılık veya kiralık olup olmadığı gibi ayrıntılar da dahil olmak üzere mülk verilerini almak ve görüntülemek için bir internet sunucusuna bağlanır. Her bir tesisi temsil eden görüntüler, NASA'nın Mars keşif araçları tarafından çekilen gerçek Mars fotoğraflarıdır.

Bu codelab'de oluşturduğunuz uygulama sürümü, resimlerden oluşan bir ızgara gösteren genel bakış sayfasını doldurur. Resimler, uygulamanızın Mars emlak web hizmetinden aldığı mülk verilerinin bir parçasıdır. Uygulamanız, resimleri yüklemek ve görüntülemek için Glide kitaplığını, resimler için ızgara düzeni oluşturmak üzere de RecyclerView kullanır. Uygulamanız, ağ hatalarını da sorunsuz bir şekilde işler.
Web URL'sinden fotoğraf göstermek basit bir işlem gibi görünse de iyi çalışması için önemli bir mühendislik çalışması gerekir. Resmin, sıkıştırılmış biçiminden Android'in kullanabileceği bir resme dönüştürülmesi için indirilmesi, arabelleğe alınması ve kodunun çözülmesi gerekir. Resim, bellek içi önbelleğe, depolama tabanlı önbelleğe veya her ikisine de önbelleğe alınmalıdır. Tüm bu işlemler, kullanıcı arayüzünün yanıt vermeye devam etmesi için düşük öncelikli arka plan iş parçacıklarında gerçekleşmelidir. Ayrıca, en iyi ağ ve CPU performansı için birden fazla resmi aynı anda getirmek ve kodunu çözmek isteyebilirsiniz. Resimleri ağdan etkili bir şekilde yüklemeyi öğrenmek başlı başına bir kod laboratuvarı olabilir.
Neyse ki resimlerinizi indirmek, arabelleğe almak, kodunu çözmek ve önbelleğe almak için Glide adlı topluluk tarafından geliştirilmiş bir kitaplığı kullanabilirsiniz. Glide, tüm bunları sıfırdan yapmanız gerektiğinde karşılaşacağınız iş yükünü önemli ölçüde azaltır.
Glide'ın temel olarak iki şeye ihtiyacı vardır:
- Yüklemek ve göstermek istediğiniz resmin URL'si.
- Bu resmi görüntülemek için bir
ImageViewnesnesi.
Bu görevde, emlak web hizmetinden tek bir resmi görüntülemek için Glide'ı nasıl kullanacağınızı öğreneceksiniz. Web hizmetinin döndürdüğü mülkler listesinde ilk Mars mülkünü temsil eden resmi gösterirsiniz. Önceki ve sonraki ekran görüntülerini aşağıda bulabilirsiniz:


1. adım: Glide bağımlılığını ekleyin
- Son codelab'deki MarsRealEstate uygulamasını açın. (Uygulama yoksa MarsRealEstateNetwork'ü buradan indirebilirsiniz.)
- Uygulamanın ne yaptığını görmek için uygulamayı çalıştırın. (Mars'ta varsayımsal olarak mevcut olan bir mülkün metin ayrıntılarını gösterir.)
- build.gradle (Module: app) dosyasını açın.
dependenciesbölümünde Glide kitaplığı için şu satırı ekleyin:
implementation "com.github.bumptech.glide:glide:$version_glide"
Sürüm numarasının proje Gradle dosyasında ayrı olarak tanımlandığını unutmayın.
- Projeyi yeni bağımlılıkla yeniden oluşturmak için Şimdi Senkronize Et'i tıklayın.
2. adım: Görünüm modelini güncelleyin
Ardından, tek bir Mars tesisi için canlı verileri içerecek şekilde OverviewViewModel sınıfını güncellersiniz.
overview/OverviewViewModel.ktadlı kişiyi aç._responseiçinLiveDatasimgesinin hemen altına tek birMarsPropertynesnesi için hem dahili (değişebilir) hem de harici (değişmez) canlı veriler ekleyin.
İstendiğindeMarsPropertysınıfını (com.example.android.marsrealestate.network.MarsProperty) içe aktarın.
private val _property = MutableLiveData<MarsProperty>()
val property: LiveData<MarsProperty>
get() = _propertygetMarsRealEstateProperties()yönteminde,_response.valuedeğerini özellik sayısına ayarlayantry/catch {}bloğunun içindeki satırı bulun. Aşağıdaki testi ekleyin.MarsPropertynesneleri varsa bu test,_propertyLiveDataözelliğinin değerinilistResultiçindeki ilk mülk olarak ayarlar.
if (listResult.size > 0) {
_property.value = listResult[0]
}Tam try/catch {} bloğu artık şu şekilde görünüyor:
try {
var listResult = getPropertiesDeferred.await()
_response.value = "Success: ${listResult.size} Mars properties retrieved"
if (listResult.size > 0) {
_property.value = listResult[0]
}
} catch (e: Exception) {
_response.value = "Failure: ${e.message}"
}res/layout/fragment_overview.xmldosyasını açın.<TextView>öğesinde,android:textdeğerinipropertyLiveDataöğesininimgSrcUrlbileşenine bağlanacak şekilde değiştirin:
android:text="@{viewModel.property.imgSrcUrl}"- Uygulamayı çalıştırın.
TextViewyalnızca ilk Mars mülkündeki resmin URL'sini gösterir. Şimdiye kadar yaptığınız tek şey, görünüm modelini ve bu URL'nin canlı verilerini ayarlamaktı.

3. adım: Bağlama bağdaştırıcısı oluşturun ve Glide'ı çağırın
Artık görüntülenecek bir resmin URL'sine sahipsiniz ve bu resmi yüklemek için Glide ile çalışmaya başlamanın zamanı geldi. Bu adımda, ImageView ile ilişkili bir XML özelliğinden URL'yi almak için bağlama bağdaştırıcısı kullanır ve resmi yüklemek için Glide'ı kullanırsınız. Bağlama bağdaştırıcıları, veri değiştiğinde özel davranış sağlamak için bir görünüm ile bağlı veriler arasında yer alan uzantı yöntemleridir. Bu durumda, özel davranış, bir URL'den resim yüklemek için Glide'ı çağırmaktır.ImageView
BindingAdapters.ktadlı kişiyi aç. Bu dosya, uygulama genelinde kullandığınız bağlama bağdaştırıcılarını içerir.bindImage()işlevi oluşturun. Bu işlev, parametre olarakImageViewveStringdeğerlerini alır. İşlevi@BindingAdapterile açıklama ekleyin.@BindingAdapteraçıklaması, veri bağlamaya bir XML öğesindeimageUrlözelliği olduğunda bu bağlama bağdaştırıcısının yürütülmesini istediğinizi bildirir. İstendiğinde
İçe aktarandroidx.databinding.BindingAdapterveandroid.widget.ImageView'ı tıklayın.
@BindingAdapter("imageUrl")
fun bindImage(imgView: ImageView, imgUrl: String?) {
}bindImage()işlevinin içine,imgUrlbağımsız değişkeni için birlet {}bloğu ekleyin:
imgUrl?.let {
}let {}bloğunun içine, URL dizesini (XML'den)Urinesnesine dönüştürmek için aşağıda gösterilen satırı ekleyin. İstendiğindeandroidx.core.net.toUriöğesini içe aktarın.
Resimleri çektiğiniz sunucu bu şemayı gerektirdiğinden sonUrinesnesinin HTTPS şemasını kullanmasını istiyorsunuz. HTTPS şemasını kullanmak içinbuildUpon.scheme("https")oluşturucuyatoUriekleyin.toUri()yöntemi, Android KTX çekirdek kitaplığındaki bir Kotlin uzantı işlevidir. Bu nedenle, yalnızcaStringsınıfının bir parçası gibi görünür.
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()- Hâlâ
let {}içindeysenizUrinesnesindeki resmiImageView'e yüklemek içinGlide.with()'i çağırın. İstendiğindecom.bumptech.glide.Glideiçe aktarın.
Glide.with(imgView.context)
.load(imgUri)
.into(imgView)4. adım: Düzeni ve parçaları güncelleyin
Glide, resmi yüklemiş olsa da henüz görülecek bir şey yok. Sonraki adım, resmi göstermek için düzeni ve parçaları ImageView ile güncellemek.
res/layout/gridview_item.xmladlı kişiyi aç. Bu, codelab'in ilerleyen bölümlerindeRecyclerViewiçindeki her öğe için kullanacağınız düzen kaynak dosyasıdır. Tek bir resmi göstermek için burada geçici olarak kullanırsınız.<ImageView>öğesinin üstüne, veri bağlama için bir<data>öğesi ekleyin veOverviewViewModelsınıfına bağlayın:
<data>
<variable
name="viewModel"
type="com.example.android.marsrealestate.overview.OverviewViewModel" />
</data>- Yeni resim yükleme bağlama bağdaştırıcısını kullanmak için
ImageViewöğesine birapp:imageUrlözelliği ekleyin:
app:imageUrl="@{viewModel.property.imgSrcUrl}"overview/OverviewFragment.ktadlı kişiyi aç.onCreateView()yönteminde,FragmentOverviewBindingsınıfını şişiren ve bağlama değişkenine atayan satırı yorum satırı yapın. Bu yalnızca geçici bir durumdur. Daha sonra bu hesaba geri döneceksiniz.
//val binding = FragmentOverviewBinding.inflate(inflater)- Bunun yerine
GridViewItemBindingsınıfını yükseltmek için bir satır ekleyin. İstendiğindecom.example.android.marsrealestate. databinding.GridViewItemBindingiçe aktarın.
val binding = GridViewItemBinding.inflate(inflater)- Uygulamayı çalıştırın. Sonuç listesinde ilk
MarsPropertyöğesindeki resmin fotoğrafını görürsünüz.
5. adım: Basit yükleme ve hata resimleri ekleyin
Glide, resmi yüklerken yer tutucu bir resim, yükleme başarısız olursa (ör. resim eksik veya bozuksa) ise hata resmi göstererek kullanıcı deneyimini iyileştirebilir. Bu adımda, bu işlevi bağlama adaptörüne ve düzene eklersiniz.
res/drawable/ic_broken_image.xmlsimgesini açın ve sağdaki Önizleme sekmesini tıklayın. Hata resmi için, yerleşik simge kitaplığında bulunan bozuk resim simgesini kullanıyorsunuz. Bu drawable vektör, simgeyi gri renkte göstermek içinandroid:tintözelliğini kullanır.

res/drawable/loading_animation.xmladlı kişiyi aç. Bu drawable,<animate-rotate>etiketiyle tanımlanan bir animasyondur. Animasyon, çizilebilir bir resmi (loading_img.xml) orta nokta etrafında döndürür. (Önizlemede animasyonu görmezsiniz.)

BindingAdapters.ktdosyasına dönün.bindImage()yönteminde,load()ileinto()arasındaapply()işlevini çağırmak içinGlide.with()çağrısınıGlide.with()olarak güncelleyin. İstenildiğindecom.bumptech.glide.request.RequestOptionsiçe aktarın.
Bu kod, yükleme sırasında kullanılacak yer tutucu yükleme resmini (loading_animationçizilebilir öğesi) ayarlar. Kod, resim yükleme başarısız olursa kullanılacak bir resim de ayarlar (broken_imageçizilebilir).bindImage()yönteminin tamamı artık şu şekilde görünür:
@BindingAdapter("imageUrl")
fun bindImage(imgView: ImageView, imgUrl: String?) {
imgUrl?.let {
val imgUri =
imgUrl.toUri().buildUpon().scheme("https").build()
Glide.with(imgView.context)
.load(imgUri)
.apply(RequestOptions()
.placeholder(R.drawable.loading_animation)
.error(R.drawable.ic_broken_image))
.into(imgView)
}
}
- Uygulamayı çalıştırın. Ağ bağlantınızın hızına bağlı olarak, Glide mülk resmini indirip gösterirken yükleme resmini kısa bir süre görebilirsiniz. Ancak ağınızı kapatsanız bile bozuk resim simgesini henüz görmezsiniz. Bu sorunu codelab'in son bölümünde düzelteceksiniz.
Uygulamanız artık internetten mülk bilgilerini yüklüyor. İlk MarsProperty liste öğesindeki verileri kullanarak görünüm modelinde bir LiveData özelliği oluşturdunuz ve bir ImageView öğesini doldurmak için bu özellik verilerindeki resim URL'sini kullandınız. Ancak hedefiniz uygulamanızın bir resim ızgarası göstermesi olduğundan RecyclerView ile GridLayoutManager kullanmak istersiniz.
1. adım: Görünüm modelini güncelleyin
Şu anda görünüm modelinde, web hizmetinden gelen yanıt listesindeki ilk MarsProperty nesnesini tutan bir _property LiveData var. Bu adımda, LiveData öğesini MarsProperty nesnelerinin tamamını içerecek şekilde değiştirirsiniz.
overview/OverviewViewModel.ktadlı kişiyi aç.- Özel
_propertydeğişkenini_propertiesolarak değiştirin. TürüMarsPropertynesnelerinin listesi olarak değiştirin.
private val _properties = MutableLiveData<List<MarsProperty>>()- Harici
propertycanlı verilerinipropertiesile değiştirin. ListeyiLiveDatatürüne de ekleyin:
val properties: LiveData<List<MarsProperty>>
get() = _propertiesgetMarsRealEstateProperties()yöntemine gidin.try {}bloğunun içinde, önceki görevde eklediğiniz testin tamamını aşağıdaki satırla değiştirin.listResultdeğişkeniMarsPropertynesnelerinin listesini içerdiğinden başarılı bir yanıt için test etmek yerine bunu_properties.valuedeğişkenine atayabilirsiniz.
_properties.value = listResulttry/catch bloğunun tamamı artık şu şekilde görünüyor:
try {
var listResult = getPropertiesDeferred.await()
_response.value = "Success: ${listResult.size} Mars properties retrieved"
_properties.value = listResult
} catch (e: Exception) {
_response.value = "Failure: ${e.message}"
}2. adım: Düzenleri ve parçaları güncelleyin
Bir sonraki adım, uygulamanın düzenini ve parçalarını tek resim görünümü yerine geri dönüşüm görünümü ve ızgara düzeni kullanacak şekilde değiştirmektir.
res/layout/gridview_item.xmladlı kişiyi aç. Veri bağlamayıOverviewViewModelolarak değiştirin ve değişkeni"property"olarak yeniden adlandırın.MarsProperty
<variable
name="property"
type="com.example.android.marsrealestate.network.MarsProperty" /><ImageView>bölümünde,app:imageUrlözelliğiniMarsPropertynesnesindeki resim URL'sine referans verecek şekilde değiştirin:
app:imageUrl="@{property.imgSrcUrl}"overview/OverviewFragment.ktadlı kişiyi aç.onCreateview()içinde,FragmentOverviewBindingöğesini genişleten satırın yorum işaretini kaldırın.GridViewBindingdeğerini artıran satırı silin veya yorum satırı haline getirin. Bu değişiklikler, son görevde yaptığınız geçici değişiklikleri geri alır.
val binding = FragmentOverviewBinding.inflate(inflater)
// val binding = GridViewItemBinding.inflate(inflater)res/layout/fragment_overview.xmladlı kişiyi aç.<TextView>öğesinin tamamını silin.- Bunun yerine, tek bir öğe için
GridLayoutManagervegrid_view_itemdüzenini kullanan şu<RecyclerView>öğesini ekleyin:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/photos_grid"
android:layout_width="0dp"
android:layout_height="0dp"
android:padding="6dp"
android:clipToPadding="false"
app:layoutManager=
"androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:spanCount="2"
tools:itemCount="16"
tools:listitem="@layout/grid_view_item" />3. adım: Fotoğraf ızgarası adaptörünü ekleyin
Artık fragment_overview düzeninde RecyclerView, grid_view_item düzeninde ise tek bir ImageView var. Bu adımda, RecyclerView adaptörü aracılığıyla verileri RecyclerView öğesine bağlarsınız.
overview/PhotoGridAdapter.ktadlı kişiyi aç.- Aşağıda gösterilen oluşturucu parametreleriyle
PhotoGridAdaptersınıfını oluşturun.PhotoGridAdaptersınıfı, oluşturucusu liste öğesi türünü, görünüm tutucuyu veDiffUtil.ItemCallbackuygulamasını gerektirenListAdaptersınıfını genişletir.
İstendiğindeandroidx.recyclerview.widget.ListAdaptervecom.example.android.marsrealestate.network.MarsPropertysınıflarını içe aktarın. Aşağıdaki adımlarda, bu oluşturucunun hata oluşturan diğer eksik kısımlarını uygulayacaksınız.
class PhotoGridAdapter : ListAdapter<MarsProperty,
PhotoGridAdapter.MarsPropertyViewHolder>(DiffCallback) {
}PhotoGridAdaptersınıfında herhangi bir yeri tıklayın veonCreateViewHolder()ileonBindViewHolder()olanListAdapteryöntemlerini uygulamak içinControl+ituşuna basın.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PhotoGridAdapter.MarsPropertyViewHolder {
TODO("not implemented")
}
override fun onBindViewHolder(holder: PhotoGridAdapter.MarsPropertyViewHolder, position: Int) {
TODO("not implemented")
}PhotoGridAdaptersınıf tanımının sonunda, az önce eklediğiniz yöntemlerden sonra, aşağıda gösterildiği gibiDiffCallbackiçin bir tamamlayıcı nesne tanımı ekleyin. İstendiğinde
İçe aktar'ıandroidx.recyclerview.widget.DiffUtiltıklayın.
TheDiffCallbackobject extendsDiffUtil.ItemCallbackwith the type of object you want to compare—MarsProperty.
companion object DiffCallback : DiffUtil.ItemCallback<MarsProperty>() {
}- Bu nesne için karşılaştırıcı yöntemleri (
areItemsTheSame()veareContentsTheSame()) uygulamak üzereControl+ituşuna basın.
override fun areItemsTheSame(oldItem: MarsProperty, newItem: MarsProperty): Boolean {
TODO("not implemented")
}
override fun areContentsTheSame(oldItem: MarsProperty, newItem: MarsProperty): Boolean {
TODO("not implemented") }areItemsTheSame()yöntemi için YAPILACAKLAR'ı kaldırın.===venewItemiçin nesne referansları aynıysatruedeğerini döndüren Kotlin'in referans eşitliği operatörünü (===) kullanın.oldItem
override fun areItemsTheSame(oldItem: MarsProperty,
newItem: MarsProperty): Boolean {
return oldItem === newItem
}areContentsTheSame()için yalnızcaoldItemvenewItemkimliğinde standart eşitlik operatörünü kullanın.
override fun areContentsTheSame(oldItem: MarsProperty,
newItem: MarsProperty): Boolean {
return oldItem.id == newItem.id
}- Hâlâ
PhotoGridAdaptersınıfının içindeyken, yardımcı nesnenin altınaRecyclerView.ViewHoldersınıfını genişletenMarsPropertyViewHolderiçin bir iç sınıf tanımı ekleyin.
İstendiğindeandroidx.recyclerview.widget.RecyclerViewvecom.example.android.marsrealestate.databinding.GridViewItemBindingöğelerini içe aktarın.MarsPropertyöğesini düzene bağlamak içinGridViewItemBindingdeğişkenine ihtiyacınız vardır. Bu nedenle, değişkeniMarsPropertyViewHolderöğesine iletin. TemelViewHoldersınıfı, oluşturucusunda bir görünüm gerektirdiğinden bağlama kök görünümünü iletirsiniz.
class MarsPropertyViewHolder(private var binding:
GridViewItemBinding):
RecyclerView.ViewHolder(binding.root) {
}MarsPropertyViewHolderiçinde,MarsPropertynesnesini bağımsız değişken olarak alan vebinding.propertydeğerini bu nesneye ayarlayan birbind()yöntemi oluşturun. Mülkü ayarladıktan sonraexecutePendingBindings()işlevini çağırın. Bu işlem, güncellemenin hemen yürütülmesine neden olur.
fun bind(marsProperty: MarsProperty) {
binding.property = marsProperty
binding.executePendingBindings()
}onCreateViewHolder()içinde TODO'yu kaldırın ve aşağıda gösterilen satırı ekleyin. İstendiğindeandroid.view.LayoutInflateriçe aktarın.onCreateViewHolder()yöntemi,GridViewItemBindingşişirilerek ve üstViewGroupbağlamınızdakiLayoutInflaterkullanılarak oluşturulan yeni birMarsPropertyViewHolderdöndürmelidir.
return MarsPropertyViewHolder(GridViewItemBinding.inflate(
LayoutInflater.from(parent.context)))onBindViewHolder()yönteminde, TODO'yu kaldırın ve aşağıda gösterilen satırları ekleyin. Burada, geçerliRecyclerViewkonumuyla ilişkiliMarsPropertynesnesini almak içingetItem()işlevini çağırır ve ardından bu özelliğiMarsPropertyViewHolderiçindekibind()yöntemine iletirsiniz.
val marsProperty = getItem(position)
holder.bind(marsProperty)4. adım: Bağlama adaptörünü ekleyin ve parçaları bağlayın
Son olarak, PhotoGridAdapter öğesini MarsProperty nesnelerinin listesiyle başlatmak için BindingAdapter kullanın. BindingAdapter kullanarak RecyclerView verilerini ayarlamak, veri bağlamanın MarsProperty nesnelerinin listesi için LiveData öğesini otomatik olarak gözlemlemesine neden olur. Ardından, MarsProperty listesi değiştiğinde bağlama bağdaştırıcısı otomatik olarak çağrılır.
BindingAdapters.ktadlı kişiyi aç.- Dosyanın sonuna, bağımsız değişken olarak
RecyclerViewveMarsPropertynesnelerinin listesini alan birbindRecyclerView()yöntemi ekleyin. Bu yöntemi@BindingAdapterile açıklayın. İstendiğinde
Importandroidx.recyclerview.widget.RecyclerViewvecom.example.android.marsrealestate.network.MarsProperty'ı tıklayın.
@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView,
data: List<MarsProperty>?) {
}bindRecyclerView()işlevinin içinderecyclerView.adapteröğesiniPhotoGridAdapterolarak yayınlayın ve verilerleadapter.submitList()öğesini çağırın. Bu, yeni bir liste kullanıma sunulduğundaRecyclerView'a bilgi verir.
İstendiğinde com.example.android.marsrealestate.overview.PhotoGridAdapter içe aktarın.
val adapter = recyclerView.adapter as PhotoGridAdapter
adapter.submitList(data)res/layout/fragment_overview.xmladlı kişiyi aç.app:listDataözelliğiniRecyclerViewöğesine ekleyin ve veri bağlama kullanarakviewmodel.propertiesolarak ayarlayın.
app:listData="@{viewModel.properties}"overview/OverviewFragment.ktadlı kişiyi aç.onCreateView()içinde,setHasOptionsMenu()çağrısından hemen önceRecyclerViewbağdaştırıcısınıbinding.photosGridiçinde yeni birPhotoGridAdapternesnesi olarak başlatın.
binding.photosGrid.adapter = PhotoGridAdapter()- Uygulamayı çalıştırın.
MarsPropertyresimlerinden oluşan bir tablo görürsünüz. Yeni resimleri görmek için kaydırdığınızda uygulama, resmi göstermeden önce yükleme ilerleme durumu simgesini gösterir. Uçak modunu açarsanız henüz yüklenmemiş resimler bozuk resim simgeleri olarak görünür.

MarsRealEstate uygulaması, bir resim getirilemediğinde bozuk resim simgesini gösteriyor. Ancak ağ olmadığında uygulama boş bir ekran gösteriyor.

Bu, iyi bir kullanıcı deneyimi değildir. Bu görevde, kullanıcıya neler olduğu hakkında daha iyi bir fikir vermek için temel hata işleme işlevini ekleyeceksiniz. İnternet bağlantısı yoksa uygulamada bağlantı hatası simgesi gösterilir. Uygulama, MarsProperty listesini getirirken yükleme animasyonunu gösterir.
1. adım: Görünüm modeline durum ekleyin
Başlamak için, web isteğinin durumunu temsil etmek üzere görünüm modelinde bir LiveData oluşturursunuz. Göz önünde bulundurulması gereken üç durum vardır: yükleme, başarılı ve başarısız. Yükleme durumu, await() çağrısındaki verileri beklerken gerçekleşir.
overview/OverviewViewModel.ktadlı kişiyi aç. Dosyanın en üstüne (içe aktarmalardan sonra, sınıf tanımından önce) tüm kullanılabilir durumları temsil eden birenumekleyin:
enum class MarsApiStatus { LOADING, ERROR, DONE }_responsesınıfındaki hem dahili hem de hariciOverviewViewModelcanlı veri tanımlarını_statusolarak yeniden adlandırın. Bu codelab'in önceki bölümlerinde_propertiesLiveDataiçin destek eklediğinizden, web hizmeti yanıtının tamamı kullanılmamıştır. Mevcut durumu takip etmek için buraya birLiveDataeklemeniz gerekir. Bu nedenle, mevcut değişkenleri yeniden adlandırabilirsiniz.
Ayrıca, türleri String olarak değiştirin.MarsApiStatus.
private val _status = MutableLiveData<MarsApiStatus>()
val status: LiveData<MarsApiStatus>
get() = _statusgetMarsRealEstateProperties()yöntemine gidin ve_responseile_statusarasındaki farkı burada da güncelleyin."Success"dizesiniMarsApiStatus.DONEdurumuna,"Failure"dizesini iseMarsApiStatus.ERRORolarak değiştirin.MarsApiStatus.LOADINGdurumunutry {}bloğunun en üstüne,await()çağrısından önce ekleyin. Bu, eş yordam çalışırken ve verileri beklerkenki ilk durumdur. Tamtry/catch {}bloğu artık şu şekilde görünüyor:
try {
_status.value = MarsApiStatus.LOADING
var listResult = getPropertiesDeferred.await()
_status.value = MarsApiStatus.DONE
_properties.value = listResult
} catch (e: Exception) {
_status.value = MarsApiStatus.ERROR
}catch {}bloğundaki hata durumundan sonra_propertiesLiveDataöğesini boş bir listeye ayarlayın. Bu işlemRecyclerViewtemizler.
} catch (e: Exception) {
_status.value = MarsApiStatus.ERROR
_properties.value = ArrayList()
}2. adım: Durum ImageView için bir bağlama bağdaştırıcısı ekleyin
Artık görünüm modelinde bir durumunuz var ancak bu yalnızca bir durum kümesi. Bunu uygulamanın kendisinde nasıl gösterebilirsiniz? Bu adımda, yükleme ve hata durumları için simgeler göstermek üzere veri bağlamaya bağlı bir ImageView kullanırsınız. Uygulama yükleme veya hata durumundayken ImageView görünür olmalıdır. Uygulama yüklendiğinde ImageView görünmez olmalıdır.
BindingAdapters.ktadlı kişiyi aç.bindStatus()adlı yeni bir bağlama bağdaştırıcısı ekleyin. Bu bağdaştırıcı, bağımsız değişken olarakImageViewveMarsApiStatusdeğerlerini alır. İstendiğindecom.example.android.marsrealestate.overview.MarsApiStatusiçe aktarın.
@BindingAdapter("marsApiStatus")
fun bindStatus(statusImageView: ImageView,
status: MarsApiStatus?) {
}- Farklı durumlar arasında geçiş yapmak için
when {}yönteminin içinebindStatus()ekleyin.
when (status) {
}when {}içinde yükleme durumu için bir durum ekleyin (MarsApiStatus.LOADING). Bu durum içinImageViewöğesini görünür olarak ayarlayın ve yükleme animasyonunu atayın. Bu, önceki görevde Glide için kullandığınız animasyon çizilebilir öğesiyle aynıdır. İstendiğindeandroid.view.Viewiçe aktarın.
when (status) {
MarsApiStatus.LOADING -> {
statusImageView.visibility = View.VISIBLE
statusImageView.setImageResource(R.drawable.loading_animation)
}
}- Hata durumu için bir durum ekleyin. Hata durumu
MarsApiStatus.ERROR'dır.LOADINGdurumu için yaptığınız gibi, durumuImageViewolarak ayarlayın ve bağlantı hatası çizilebilir öğesini yeniden kullanın.
MarsApiStatus.ERROR -> {
statusImageView.visibility = View.VISIBLE
statusImageView.setImageResource(R.drawable.ic_connection_error)
}- Tamamlandı durumu için bir durum ekleyin (
MarsApiStatus.DONE). Burada başarılı bir yanıt var. Bu nedenle, durumu gizlemek içinImageViewdurumunun görünürlüğünü kapatın.
MarsApiStatus.DONE -> {
statusImageView.visibility = View.GONE
}3. adım: Durum ImageView'ı düzene ekleyin
res/layout/fragment_overview.xmladlı kişiyi aç.RecyclerViewöğesinin altında,ConstraintLayoutöğesinin içine aşağıda gösterilenImageViewöğesini ekleyin.
BuImageViewöğesi,RecyclerViewöğesiyle aynı kısıtlamalara sahiptir. Ancak genişlik ve yükseklik, görüntüyü doldurmak için resmi uzatmak yerine resmi ortalamak içinwrap_contentkullanır. Ayrıca, görünüm modelindeki durum özelliği değiştiğindeapp:marsApiStatusgörünümünüze yapılan görünüm çağrısını içerenBindingAdapterözelliğine de dikkat edin.
<ImageView
android:id="@+id/status_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:marsApiStatus="@{viewModel.status}" />- Eksik ağ bağlantısını simüle etmek için emülatörünüzde veya cihazınızda uçak modunu açın. Uygulamayı derleyip çalıştırın ve hata resminin göründüğünü fark edin:

- Uygulamayı kapatmak için Geri düğmesine dokunun ve uçak modunu kapatın. Uygulamayı döndürmek için son kullanılanlar ekranını kullanın. Ağ bağlantınızın hızına bağlı olarak, resimler yüklenmeye başlamadan önce uygulama web hizmetini sorguladığında çok kısa süreli bir yükleme çarkı görebilirsiniz.
Android Studio projesi: MarsRealEstateGrid
- Resim yönetme sürecini basitleştirmek için uygulamanızdaki resimleri indirmek, arabelleğe almak, kodunu çözmek ve önbelleğe almak üzere Glide kitaplığını kullanın.
- Glide, internetten bir resim yüklemek için iki şeye ihtiyaç duyar: resmin URL'si ve resmi yerleştireceği bir
ImageViewnesnesi. Bu seçenekleri belirtmek için Glide ileload()veinto()yöntemlerini kullanın. - Bağlama bağdaştırıcıları, bir görünüm ile bu görünümün bağlı verileri arasında yer alan uzantı yöntemleridir. Bağlama bağdaştırıcıları, veriler değiştiğinde özel davranışlar sağlar. Örneğin, bir URL'den bir
ImageViewiçine resim yüklemek için Glide'ı çağırmak gibi. - Bağlama adaptörleri,
@BindingAdapterek açıklamasıyla açıklama eklenmiş uzantı yöntemleridir. - Glide isteğine seçenek eklemek için
apply()yöntemini kullanın. Örneğin, yükleme çizilebilir öğesini belirtmek içinapply()ileplaceholder()'i, hata çizilebilir öğesini belirtmek içinapply()ileerror()'ı kullanın. - Resimlerden oluşan bir ızgara oluşturmak için
RecyclerViewileGridLayoutManagerkullanın. - Özellikler listesi değiştiğinde güncel kalması için
RecyclerViewile düzen arasında bir bağlama bağdaştırıcısı kullanın.
Udacity kursu:
Android geliştirici belgeleri:
Diğer:
Bu bölümde, bir eğitmenin yönettiği kurs kapsamında bu codelab'i tamamlayan öğrenciler için olası ödevler listelenmektedir. Eğitmen, aşağıdakileri yapmalıdır:
- Gerekirse ödev atayın.
- Öğrencilere ev ödevi ödevlerini nasıl göndereceklerini bildirin.
- Ödevlere not verin.
Eğitmenler bu önerileri istedikleri kadar kullanabilir ve uygun olduğunu düşündükleri diğer ödevleri verebilirler.
Bu codelab'i kendi başınıza tamamlıyorsanız bilginizi test etmek için bu ödevleri kullanabilirsiniz.
Bu soruları yanıtlayın
1. Soru
Yüklenen resmi içerecek ImageView öğesini belirtmek için hangi Glide yöntemini kullanıyorsunuz?
▢ into()
▢ with()
▢ imageview()
▢ apply()
2. Soru
Glide yüklenirken gösterilecek yer tutucu resmi nasıl belirtirsiniz?
▢ into() yöntemini çizilebilir bir öğeyle kullanın.
▢ RequestOptions() kullanın ve placeholder() yöntemini çizilebilir bir öğeyle çağırın.
▢ Glide.placeholder özelliğini çizilebilir bir öğeye atayın.
▢ RequestOptions() kullanın ve loadingImage() yöntemini çizilebilir bir öğeyle çağırın.
3. Soru
Bir yöntemin bağlayıcı adaptör olduğunu nasıl belirtirsiniz?
▢ LiveData üzerinde setBindingAdapter() yöntemini çağırın.
▢ Yöntemi BindingAdapters.kt adlı bir Kotlin dosyasına yerleştirin.
▢ XML düzeninde android:adapter özelliğini kullanın.
▢ Yöntemi @BindingAdapter ile açıklayın.
Sonraki derse başlayın:
Bu kurstaki diğer codelab'lerin bağlantılarını Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında bulabilirsiniz.