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, web hizmetinden veri almayı ve yanıtı veri nesnesine ayrıştırmayı öğrendiniz. Bu codelab'de, web URL'sinden fotoğraf yüklemek ve görüntülemek için bu bilgilere dayanarak hareket edeceksiniz. Ayrıca, RecyclerView
oluşturmayı ve genel bakış sayfasında bir tablo ızgarasını görüntülemek için de kullanabilirsiniz.
Bilmeniz gerekenler
- Parça oluşturma ve kullanma.
- Görünüm modelleri, görünüm modeli fabrikaları, dönüşümler ve
LiveData
dahil olmak üzere mimari bileşenlerin nasıl kullanılacağı. - REST web hizmetinden JSON alma ve Retrofit ile Moshi kitaplıklarını kullanarak bu verileri Kotlin nesnelerine ayrıştırma.
RecyclerView
ile tablo düzeni oluşturma.Adapter
,ViewHolder
veDiffUtil
nasıl işler?
Neler öğreneceksiniz?
- Web URL'sinden bir resim yüklemek ve görüntülemek için Kaydırma kitaplığını kullanma.
- Resim ızgarası görüntülemek için
RecyclerView
ve ızgara adaptörü nasıl kullanılır? - Resimler indirilirken ve görüntülenirken olası hataları ele alma.
Ne yaparsınız?
- MarsRealEstate uygulamasında değişiklik yaparak Mars mülkü verilerinden resim URL'sini alın ve bu görseli yükleyip görüntülemek için Kaydır'ı kullanın.
- Uygulamaya bir yükleme animasyonu ve hata simgesi ekleyin.
- Mars mülkü resim ızgarasını görüntülemek için
RecyclerView
kullanın. RecyclerView
cihazına durum ve hata işleme özelliklerini ekleyin.
Bu codelab'de (ve ilgili codelab'lerde) MarsRealEstate adında, Mars'ta satılık mülkleri gösteren bir uygulamayla çalışıyorsunuz. Uygulama, fiyat bilgisi ve mülkün satılık veya kiralık olup olmadığı gibi ayrıntılar dahil olmak üzere tesis verilerini almak ve görüntülemek için bir internet sunucusuna bağlanır. Her mülkü temsil eden resimler, Mars'ın Mars gezginlerinden çekilen Mars'ın gerçek fotoğraflarıdır.
Bu codelab'de oluşturduğunuz uygulamanın sürümü, bir tablo ızgarası görüntüleyen genel bakış sayfası ile doldurulur. 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 Kaydırarak kitaplığı ve resimler için tablo düzeni oluşturmak üzere bir RecyclerView
kullanır. Uygulamanız ayrıca ağ hatalarını zarif bir şekilde işleyebilir.
Web URL'sinden bir fotoğraf görüntülemek basit bir işlem gibi görünse de fotoğrafı iyi bir şekilde işlemesi için epey mühendislik yapıldı. Resmin indirilmiş olması, arabelleğe alınması ve sıkıştırılmış biçiminden Android'in kullanabileceği bir resme dönüştürülmesi gerekir. Resim; bellek içi bir önbellek, depolamaya dayalı önbellek veya her ikisi için de önbelleğe alınmalıdır. Kullanıcı arayüzünün yanıt vermeye devam etmesi için tüm bu işlemleri düşük öncelikli arka plan mesaj dizilerinde gerçekleştirmeniz gerekir. Ayrıca, en iyi ağ ve CPU performansı için aynı anda birden fazla görüntü getirmek ve kodu çözmek isteyebilirsiniz. Ağdan resimleri etkili bir şekilde nasıl yükleyeceğinizi öğrenmek tek başına bir codelab olabilir.
Neyse ki, resimlerinizi indirmek, arabelleğe almak, çözümlemek ve önbelleğe almak için Glide adlı, topluluk tarafından geliştirilmiş bir kitaplığı kullanabilirsiniz. Kaydırarak tüm bunları sıfırdan yapmak zorunda kalacağınızdan çok daha az iş yaparsınız.
Kaydırarak iki temel koşul gereklidir:
- Yüklemek ve göstermek istediğiniz resmin URL'si.
- Bu resmi görüntülemek için bir
ImageView
nesnesi.
Bu görevde emlak web hizmetinden tek bir resim görüntülemek için Kaydırarak kullanmayı öğreneceksiniz. Web hizmetinin döndürdüğü mülkler listesinde ilk Mars mülkünü temsil eden resmi gösterirsiniz. İşte önceki ve sonraki ekran görüntüleri:
1. Adım: Kaydırmalı bağımlılık ekleyin
- Son codelab'den MarsRealEstate uygulamasını açın. (Uygulamanız yoksa MarsRealEstateNetwork'ü indirebilirsiniz.)
- Ne işe yaradığını görmek için uygulamayı çalıştırın. (Mars'ta mevcut olabilecek farazi bir mülkün metin ayrıntılarını görüntüler.)
- build.gradle (Modül: uygulama) bölümünü açın.
dependencies
bölümünde, Kaydırarak kitaplık için bu 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 Sync Now'ı (Şimdi Senkronize Et) tıklayın.
2. Adım: Görünüm modelini güncelleyin
Sonra, OverviewViewModel
sınıfını tek bir Mars mülkünün canlı verilerini içerecek şekilde güncellersiniz.
overview/OverviewViewModel.kt
'yi açın._response
içinLiveData
öğesinin hemen altına, tek birMarsProperty
nesnesinin hem dahili (değişebilir) hem de harici (sabit) canlı verileri ekleyin.
İstendiğindeMarsProperty
sınıfını (com.example.android.marsrealestate.network.MarsProperty
) içe aktarın.
private val _property = MutableLiveData<MarsProperty>()
val property: LiveData<MarsProperty>
get() = _property
getMarsRealEstateProperties()
yönteminde,try/catch {}
blokunun içinde_response.value
değerini özellik sayısına ayarlayan satırı bulun. Aşağıda gösterilen testi ekleyin.MarsProperty
nesnesi kullanılabiliyorsa bu test_property
LiveData
değerinilistResult
öğesindeki ilk mülke ayarlar.
if (listResult.size > 0) {
_property.value = listResult[0]
}
try/catch {}
blokunun tamamı 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.xml
dosyasını açın.<TextView>
öğesindeandroid:text
öğesiniproperty
LiveData
öğesininimgSrcUrl
bileşenine bağlamak için değiştirin:
android:text="@{viewModel.property.imgSrcUrl}"
- Uygulamayı çalıştırın.
TextView
simgesi, yalnızca ilk Mars mülkündeki resmin URL'sini gösterir. Şu ana kadar tek yapmanız gereken, görüntüleme modelini ve bu URL'nin canlı verilerini ayarlamak.
3. Adım: Bir bağlayıcı adaptörü oluşturun ve Kaydır'ı arayın
Artık görüntülenecek resmin URL'sine sahipsiniz ve artık bu resmi yüklemek için Kaydırarak çalışmaya başlayabilirsiniz. Bu adımda, URL'yi bir ImageView
ile ilişkilendirilmiş XML özelliğinden almak için bir bağlama adaptörü kullanırsınız ve resmi yüklemek için Kaydırarak kullanırsınız. Bağlama adaptörleri, veriler değiştiğinde özel davranış sağlamak için bir görünüm ve bağlı veriler arasında yer alan uzantı yöntemleridir. Bu durumda özel davranış, URL'deki bir resmi ImageView
ürününe yüklemek için Glide'ı çağırmaktır.
BindingAdapters.kt
'yi açın. Bu dosya, uygulama genelinde kullandığınız bağlama adaptörlerini içerir.ImageView
veString
parametrelerini alan birbindImage()
işlevi oluşturun. İşlevde@BindingAdapter
ile ek açıklama oluşturun.@BindingAdapter
açıklaması, bir XML öğesiimageUrl
özelliğine sahip olduğunda veri bağlamanın bu bağlama adaptörünün yürütülmesini istediğinizi belirtir.
İstendiğindeandroidx.databinding.BindingAdapter
veandroid.widget.ImageView
içe aktarın.
@BindingAdapter("imageUrl")
fun bindImage(imgView: ImageView, imgUrl: String?) {
}
bindImage()
işlevinin içinde,imgUrl
bağımsız değişkeni için birlet {}
bloğu ekleyin:
imgUrl?.let {
}
- URL dizesini (XML'den) bir
Uri
nesnesine dönüştürmek içinlet {}
blokunun içinde, aşağıda gösterilen satırı ekleyin. İstek üzerineandroidx.core.net.toUri
içe aktarın.
Resimleri aldığınız sunucu bu şemayı gerektirdiğinden HTTPS şemasının sonUri
nesnesini kullanmasını istiyorsunuz. HTTPS şemasını kullanmak içintoUri
oluşturucuyabuildUpon.scheme("https")
ekleyin.toUri()
yöntemi, Android KTX temel kitaplığından Kotlin uzantısı işlevidir. Bu nedenle,String
sınıfının bir parçasıdır.
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
- Hâlâ
let {}
içinde,Uri
nesnesindeki resmiImageView
içine yüklemek üzereGlide.with()
çağrısı yapın. İstendiğindecom.bumptech.glide.Glide
iç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örüntülemek için düzeni ve parçaları bir ImageView
ile güncellemektir.
res/layout/gridview_item.xml
'yi açın. Bu, codelab'in ilerleyen kısımlarındaRecyclerView
içindeki her öğe için kullanacağınız düzen kaynağı dosyasıdır. Yalnızca geçici bir resim göstermek için geçici olarak burada kullanırsınız.<ImageView>
öğesinin üzerine, veri bağlama için bir<data>
öğesi ekleyin veOverviewViewModel
sınıfına bağlayın:
<data>
<variable
name="viewModel"
type="com.example.android.marsrealestate.overview.OverviewViewModel" />
</data>
- Yeni resim yükleme bağlama adaptörünü kullanmak için
ImageView
öğesine birapp:imageUrl
özelliği ekleyin:
app:imageUrl="@{viewModel.property.imgSrcUrl}"
overview/OverviewFragment.kt
'yi açın.onCreateView()
yönteminde,FragmentOverviewBinding
sınıfını şişiren ve bağlama değişkenine atayan satıra yorum yapın. Bu geçici bir durumdur ve daha sonra tekrar deneyebilirsiniz.
//val binding = FragmentOverviewBinding.inflate(inflater)
- Bunun yerine,
GridViewItemBinding
sınıfını şişirmek için bir satır ekleyin. İstendiğindecom.example.android.marsrealestate. databinding.GridViewItemBinding
içe aktarın.
val binding = GridViewItemBinding.inflate(inflater)
- Uygulamayı çalıştırın. Artık sonuç listesinde ilk
MarsProperty
kareye ait fotoğrafın fotoğrafını görürsünüz.
5. Adım: Basit yükleme ve hata resimleri ekleyin
Kaydırarak resim yüklenirken yer tutucu resim, yükleme başarısız olursa (ör. resim eksikse veya bozulmuşsa) bir 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.xml
web sitesini 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 vektör çizimi, simgeyi gri yapmak içinandroid:tint
özelliğini kullanır.
res/drawable/loading_animation.xml
'yi açın. Bu çizim,<animate-rotate>
etiketiyle tanımlanan bir animasyondur. Animasyon, bir resmi (loading_img.xml
) orta noktanın etrafında çizilebilir. (Animasyonu önizlemede görmezsiniz.)
BindingAdapters.kt
dosyasına dönün.bindImage()
yönteminde,load()
ileinto()
arasındakiapply()
işlevini çağırmak için aramayıGlide.with()
olarak güncelleyin. İstendiğindecom.bumptech.glide.request.RequestOptions
öğesini içe aktarın.
Bu kod, yükleme sırasında kullanılacak yer tutucu yükleme resmini (loading_animation
çekilebilir) ayarlar. Kod ayrıca, resim yükleme başarısız olursa (broken_image
çekilebilir) kullanılacak bir resim ayarlar. TambindImage()
yöntemi 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, Kaydırma özelliği indirilirken yükleme resmini kısa bir süre içinde görebilirsiniz. Ancak ağınızı kapatsanız bile bozuk resim simgesini göremezsiniz. Bunu codelab'in son bölümünde düzeltirsiniz.
Uygulamanız artık mülk bilgilerini internette yüklüyor. İlk MarsProperty
liste öğesindeki verileri kullanarak görünüm modelinde bir LiveData
özelliği oluşturdunuz ve ImageView
özelliğini doldurmak için bu mülk verilerinden alınan resim URL'sini kullandınız. Ancak uygulamanızın amacı, resimlerden oluşan bir tablo görüntülemektir. Bu nedenle GridLayoutManager
içeren bir RecyclerView
kullanmak istersiniz.
1. Adım: Görünüm modelini güncelleyin
Şu anda, görüntüleme modelinde, web hizmetindeki yanıt listesinde ilki olan MarsProperty
MarsProperty
nesnesini içeren bir _property
LiveData
bulunmaktadır. Bu adımda, LiveData
öğesini MarsProperty
nesne listesinin tamamını içerecek şekilde değiştirirsiniz.
overview/OverviewViewModel.kt
'yi açın.- Gizli
_property
değişkenini_properties
olarak değiştirin. Türü,MarsProperty
nesnelerinin listesi olacak şekilde değiştirin.
private val _properties = MutableLiveData<List<MarsProperty>>()
- Harici
property
canlı verileriniproperties
ile değiştirin. Listeyi burayaLiveData
türüne de ekleyin:
val properties: LiveData<List<MarsProperty>>
get() = _properties
- Aşağı kaydırarak
getMarsRealEstateProperties()
yöntemine gidin.try {}
blokunun içinde, önceki görevde eklediğiniz testin tamamını aşağıda gösterilen satırla değiştirin.listResult
değişkeni birMarsProperty
nesnesinin listesini içerdiğinden, başarılı bir yanıt için test etmek yerine_properties.value
öğesini atayabilirsiniz.
_properties.value = listResult
try/catch
blokunun tamamı artık şöyle görünür:
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
Sonraki adım, tek bir resim görünümü yerine geri dönüşüm görünümü ve ızgara düzeni kullanmak için uygulamanın düzenini ve parçalarını değiştirmektir.
res/layout/gridview_item.xml
'yi açın.OverviewViewModel
olan veri bağlamayıMarsProperty
olarak değiştirin ve değişkeni"property"
olarak yeniden adlandırın.
<variable
name="property"
type="com.example.android.marsrealestate.network.MarsProperty" />
<ImageView>
içindeapp:imageUrl
özelliğini,MarsProperty
nesnesindeki resim URL'sine başvuracak şekilde değiştirin:
app:imageUrl="@{property.imgSrcUrl}"
overview/OverviewFragment.kt
'yi açın.onCreateview()
yılındaFragmentOverviewBinding
şişiren satırın açıklamasını kaldırın.GridViewBinding
şişiren satırı silin veya şişirin. Bu değişiklikler son görevde geçici olarak yaptığınız değişiklikleri geri alır.
val binding = FragmentOverviewBinding.inflate(inflater)
// val binding = GridViewItemBinding.inflate(inflater)
res/layout/fragment_overview.xml
'yi açın.<TextView>
öğesinin tamamını silin.- Bunun yerine, tek bir öğe için
GridLayoutManager
vegrid_view_item
düzenini kullanan bu<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, verileri bir RecyclerView
adaptörü üzerinden RecyclerView
'a bağlarsınız.
overview/PhotoGridAdapter.kt
'yi açın.- Oluşturucu parametreleriyle birlikte aşağıda gösterilen
PhotoGridAdapter
sınıfını oluşturun.PhotoGridAdapter
sınıfı, oluşturucunun liste öğesi türü, görüntüleme sahibi veDiffUtil.ItemCallback
uygulamasına ihtiyacı olanListAdapter
kapsamını genişletir.
İstendiğindeandroidx.recyclerview.widget.ListAdapter
vecom.example.android.marsrealestate.network.MarsProperty
sınıflarını içe aktarın. Aşağıdaki adımlarda, bu oluşturucunun hata oluşturan diğer eksik bölümlerini uyguluyorsunuz.
class PhotoGridAdapter : ListAdapter<MarsProperty,
PhotoGridAdapter.MarsPropertyViewHolder>(DiffCallback) {
}
onCreateViewHolder()
veonBindViewHolder()
olanListAdapter
yöntemlerini uygulamak içinPhotoGridAdapter
sınıfının herhangi bir yerini tıklayın veControl+i
tuş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")
}
PhotoGridAdapter
sınıf tanımının sonuna, yeni eklediğiniz yöntemlerden sonra, aşağıda gösterildiği gibiDiffCallback
için bir tamamlayıcı nesne tanımı ekleyin.
İstendiğindeandroidx.recyclerview.widget.DiffUtil
içe aktarın.DiffCallback
nesnesiDiffUtil.ItemCallback
öğesini, karşılaştırmak istediğiniz nesnenin türüyle genişletir.MarsProperty
companion object DiffCallback : DiffUtil.ItemCallback<MarsProperty>() {
}
- Bu nesne için karşılaştırıcı yöntemlerini uygulamak üzere
Control+i
tuşuna basın (areItemsTheSame()
veareContentsTheSame()
).
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 yapılacaklar listesini kaldırın. Kotlin's yönlendirmeli eşitlik operatörünü (===
) kullanın.oldItem
venewItem
için nesne referansları aynıysatrue
sonucunu döndürür.
override fun areItemsTheSame(oldItem: MarsProperty,
newItem: MarsProperty): Boolean {
return oldItem === newItem
}
areContentsTheSame()
için yalnızcaoldItem
venewItem
kimliğine sahip standart eşitlik operatörünü kullanın.
override fun areContentsTheSame(oldItem: MarsProperty,
newItem: MarsProperty): Boolean {
return oldItem.id == newItem.id
}
- Hâlâ
PhotoGridAdapter
sınıfının içinde, tamamlayıcı nesnenin altına,RecyclerView.ViewHolder
kapsamını genişletenMarsPropertyViewHolder
için bir iç sınıf tanımı ekleyin.
İstendiğindeandroidx.recyclerview.widget.RecyclerView
vecom.example.android.marsrealestate.databinding.GridViewItemBinding
içe aktarın.MarsProperty
öğesini düzene bağlamak içinGridViewItemBinding
değişkenini kullanmanız gerekir. Bu nedenle değişkeniMarsPropertyViewHolder
öğesine geçirin. TemelViewHolder
sınıfı, oluşturucuda bir görünüm gerektirdiğinden bunu bağlama kök görünümüne geçirirsiniz.
class MarsPropertyViewHolder(private var binding:
GridViewItemBinding):
RecyclerView.ViewHolder(binding.root) {
}
MarsPropertyViewHolder
içinde,MarsProperty
nesnesini bağımsız değişken olarak alıp bu nesneyibinding.property
olarak ayarlayan birbind()
yöntemi oluşturun. Mülkü ayarladıktan sonraexecutePendingBindings()
öğesini çağırarak güncellemenin hemen yürütülmesini sağlayın.
fun bind(marsProperty: MarsProperty) {
binding.property = marsProperty
binding.executePendingBindings()
}
onCreateViewHolder()
sayfasında, YAPILACAKLAR bölümünü kaldırın ve aşağıda gösterilen satırı ekleyin. İstendiğindeandroid.view.LayoutInflater
içe aktarın.onCreateViewHolder()
yönteminin,GridViewItemBinding
'ın şişirilmesi ve üstViewGroup
bağlamınınLayoutInflater
kullanılmasıyla oluşturulan yeni birMarsPropertyViewHolder
döndürmesi gerekir.
return MarsPropertyViewHolder(GridViewItemBinding.inflate(
LayoutInflater.from(parent.context)))
onBindViewHolder()
yönteminde, YAPILACAKLAR bölümünü kaldırın ve aşağıda gösterilen satırları ekleyin. Burada, mevcutRecyclerView
konumuyla ilişkilendirilmişMarsProperty
nesnesini almak içingetItem()
öğesini çağırır ve ardından bu özelliğiMarsPropertyViewHolder
içindekibind()
yöntemine geçirirsiniz.
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
nesneleri listesiyle başlatmak için bir BindingAdapter
kullanın. RecyclerView
verilerini ayarlamak için BindingAdapter
kullanılması, veri bağlamanın MarsProperty
nesne listesinde LiveData
değerinin otomatik olarak gözlemlenmesine neden olur. Daha sonra, MarsProperty
listesi değiştiğinde bağlama adaptörü otomatik olarak çağrılır.
BindingAdapters.kt
'yi açın.- Dosyanın sonuna
RecyclerView
bağımsız değişken olarak birbindRecyclerView()
yöntemi veMarsProperty
nesnelerinin bir listesini ekleyin. Bu yönteme@BindingAdapter
ile ek açıklama ekleyin.
İstendiğindeandroidx.recyclerview.widget.RecyclerView
vecom.example.android.marsrealestate.network.MarsProperty
içe aktarın.
@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView,
data: List<MarsProperty>?) {
}
bindRecyclerView()
işlevinin içinderecyclerView.adapter
öğesiniPhotoGridAdapter
öğesine yayınlayın ve verilerle birlikteadapter.submitList()
öğesini çağırın. Bu,RecyclerView
adlı kullanıcıya yeni bir liste hazır olduğunda bildirir.
İ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.xml
'yi açın.app:listData
özelliğiniRecyclerView
öğesine ekleyin ve veri bağlamayı kullanarakviewmodel.properties
olarak ayarlayın.
app:listData="@{viewModel.properties}"
overview/OverviewFragment.kt
'yi açın.onCreateView()
içinde,setHasOptionsMenu()
çağrısından hemen öncebinding.photosGrid
içinRecyclerView
adaptörünü yeni birPhotoGridAdapter
nesnesine başlatın.
binding.photosGrid.adapter = PhotoGridAdapter()
- Uygulamayı çalıştırın. Izgara
MarsProperty
resim görürsünüz. Yeni resimleri görmek için sayfayı kaydırdığınızda uygulama, resmin kendisini görüntülemeden önce yükleme ilerleme durumu simgesini gösterir. Uçak modunu açarsanız henüz yüklenmeyen resimler bozuk resim simgeleri olarak görünür.
Bir resim getirilemediğinde MarsRealEstate uygulamasında bozuk resim simgesi görüntülenir. Ancak ağ olmadığında uygulama boş bir ekran gösterir.
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şlemeyi eklersiniz. İnternet yoksa uygulama bağlantı hatası simgesini gösterir. Uygulama, MarsProperty
listesini getirirken yükleme animasyonunu gösterir.
1. Adım: Görünüm modeline durum ekleyin
Başlamak için, görünüm modelinde web isteğinin durumunu temsil eden bir LiveData
oluşturursunuz. Üç temel nokta vardır: yükleme, başarılı ve başarısız. Yükleme durumu, await()
çağrısında veri beklerken gerçekleşir.
overview/OverviewViewModel.kt
'yi açın. Dosyanın en üstüne (içe aktarmalardan sonra, sınıf tanımından önce) mevcut tüm durumları temsil edenenum
ekleyin:
enum class MarsApiStatus { LOADING, ERROR, DONE }
OverviewViewModel
sınıfındaki dahili ve harici_response
canlı veri tanımlarını_status
olarak yeniden adlandırın. Bu codelab'de daha önce_properties
LiveData
için destek eklediğiniz için web hizmeti yanıtı tam olarak kullanılmadı. Mevcut değişkenleri takip edebilmek için burada birLiveData
öğesine ihtiyacınız vardır. Böylece yalnızca mevcut değişkenleri yeniden adlandırabilirsiniz.
Ayrıca, String
olan türleri MarsApiStatus.
olarak değiştir
private val _status = MutableLiveData<MarsApiStatus>()
val status: LiveData<MarsApiStatus>
get() = _status
getMarsRealEstateProperties()
yöntemine ilerleyin ve_response
öğesini de_status
olarak güncelleyin."Success"
dizesiniMarsApiStatus.DONE
durumuna,"Failure"
dizesini iseMarsApiStatus.ERROR
olarak değiştirin.await()
çağrısından önce,try {}
blokunun üst kısmına birMarsApiStatus.LOADING
durumu ekleyin. Bu, coroutine çalışırken ve verileri beklerken başlangıç durumudur.try/catch {}
blokunun tamamı 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 {}
blokundaki hata durumundan sonra_properties
LiveData
alanını boş bir listeye ayarlayın. Bu işlem,RecyclerView
anahtarını temizler.
} catch (e: Exception) {
_status.value = MarsApiStatus.ERROR
_properties.value = ArrayList()
}
2. Adım: ImageView durumu için bir bağlayıcı adaptörü ekleyin
Artık görünüm modelinde bir durumunuz var ancak bu yalnızca bir grup durum. Uygulamanın kendisinin görünmesini nasıl sağlıyorsunuz? Bu adımda, yükleme ve hata durumlarına ilişkin simgeleri görüntülemek için veri bağlamaya bağlı bir ImageView
kullanırsınız. Uygulama, yükleme durumunda veya hata durumundayken ImageView
öğesi görünür olmalıdır. Uygulamanın yüklenmesi tamamlandığında ImageView
görünmez olmalıdır.
BindingAdapters.kt
'yi açın. Bağımsız değişken olarakImageView
veMarsApiStatus
değerini alan,bindStatus()
adlı yeni bir bağlayıcı adaptörü ekleyin. İstendiğindecom.example.android.marsrealestate.overview.MarsApiStatus
içe aktarın.
@BindingAdapter("marsApiStatus")
fun bindStatus(statusImageView: ImageView,
status: MarsApiStatus?) {
}
- Farklı durumlar arasında geçiş yapmak için
bindStatus()
yönteminin içine birwhen {}
ekleyin.
when (status) {
}
when {}
içinde, yükleme durumu için bir destek kaydı (MarsApiStatus.LOADING
) ekleyin. Bu durumda,ImageView
öğesini görünür olarak ayarlayın ve yükleme animasyonunu atayın. Bu, önceki görevde Kayan için kullandığınız animasyonla aynı çizim olabilir. İstendiğindeandroid.view.View
içe aktarın.
when (status) {
MarsApiStatus.LOADING -> {
statusImageView.visibility = View.VISIBLE
statusImageView.setImageResource(R.drawable.loading_animation)
}
}
- Hata durumu için (
MarsApiStatus.ERROR
) bir destek kaydı ekleyin.LOADING
durumunda yaptığınıza benzer şekilde,ImageView
durumunu görünür olarak ayarlayın ve bağlantı hatasını çizilebilir olarak yeniden kullanın.
MarsApiStatus.ERROR -> {
statusImageView.visibility = View.VISIBLE
statusImageView.setImageResource(R.drawable.ic_connection_error)
}
- Bitti durumu için bir destek kaydı ekleyin:
MarsApiStatus.DONE
. Burada başarılı bir yanıt verdiğinizden gizlemek içinImageView
durumunun görünürlüğünü kapatın.
MarsApiStatus.DONE -> {
statusImageView.visibility = View.GONE
}
3. Adım: Düzene ImageView durumunu ekleyin
res/layout/fragment_overview.xml
'yi açın.RecyclerView
öğesinin altında,ConstraintLayout
altına, aşağıda gösterilenImageView
öğesini ekleyin.
BuImageView
,RecyclerView
ile aynı kısıtlamalara sahiptir. Ancak genişlik ve yükseklik, görünümü doldurmak için resmi uzatmak yerinewrap_content
kullanarak görüntüyü ortalar. Ayrıca, görünüm modelindeki durum özelliği değiştiğinde, görünümünBindingAdapter
çağrısı yaptığıapp:marsApiStatus
ö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 bir ağ bağlantısı 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üğüne dikkat edin:
- Uygulamayı kapatmak ve uçak modunu kapatmak için Geri düğmesine dokunun. Uygulamayı döndürmek için son kullanılan ekranlarından yararlanın. Ağ bağlantınızın hızına bağlı olarak, resimler yüklenmeye başlamadan önce uygulama web hizmetini sorgularken son derece kısa bir yükleme döner simgesi görebilirsiniz.
Android Studio projesi: MarsRealEstateEnlem
- Resimleri yönetme sürecini basitleştirmek için Kaydırma kitaplığını kullanarak uygulamanızda resimleri indirin, arabelleğe alın, kodunu çözün ve önbelleğe alın.
- Glide, internetten bir resim yüklemek için iki şeye ihtiyaç duyar: bir resmin URL'si ve resmin yerleştirileceği
ImageView
nesnesi. Bu seçenekleri belirtmek için Kaydırarakload()
veinto()
yöntemlerini kullanın. - Bağlama adaptörleri, bir görünüm ile görünüm sınırı verileri arasında yer alan uzantı yöntemleridir. Bağlama adaptörleri, veriler değiştiğinde özel bir davranış sağlar (örneğin, bir URL'den
ImageView
içerisine resim yüklemek için Glide'ı çağırmak). - Bağlama adaptörleri,
@BindingAdapter
ek açıklamasıyla birlikte kullanılan uzantı yöntemleridir. - Kaydırma isteğine seçenek eklemek için
apply()
yöntemini kullanın. Örneğin, bir yükleme çekilebilirliğini belirtmek içinplaceholder()
ileapply()
, çekilebilir bir hata belirtmek içinseerror()
ile birlikteapply()
kullanın. - Izgara resim oluşturmak için
GridLayoutManager
içeren birRecyclerView
kullanın. - Değiştiğinde özellik listesini güncellemek için
RecyclerView
ile düzen arasında bir bağlayıcı adaptörü kullanın.
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
Yüklenen resmi içeren ImageView
öğesini belirtmek için hangi Kaydırma yöntemini kullanıyorsunuz?
makbuz into()
makbuz with()
makbuz imageview()
makbuz apply()
2. Soru
Glide yüklenirken gösterilecek bir yer tutucu resmi nasıl belirtirsiniz?
▢ Çizilebilir into()
yöntemini kullanın.
▢ RequestOptions()
yöntemini kullanın ve placeholder()
yöntemini çekilebilir olarak çağırın.
▢ Glide.placeholder
özelliğini çekilebilir duruma atayın.
▢ RequestOptions()
yöntemini kullanın ve loadingImage()
yöntemini çekilebilir olarak çağırın.
3. Soru
Bir yöntemin bağlayıcı adaptörü olduğunu nasıl belirtirsiniz?
▢ LiveData
üzerindeki setBindingAdapter()
yöntemini arayın.
▢ Yöntemi BindingAdapters.kt
adlı bir Kotlin dosyasına koyun.
▢ XML düzeninde android:adapter
özelliğini kullanın.
▢ Yönteme @BindingAdapter
ile ek açıklama ekleyin.
Sonraki derse başlayın:
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.