From ee2534e8bdf3ee2b5097cc2e23f105d8b5cbcba1 Mon Sep 17 00:00:00 2001 From: 62160052 <62160052@go.buu.ac.th> Date: Sat, 24 Sep 2022 20:44:34 +0700 Subject: [PATCH] Add the binding adapter and connect the parts --- .../executionHistory/executionHistory.lock | Bin 17 -> 17 bytes .gradle/7.3.3/fileHashes/fileHashes.bin | Bin 76315 -> 76915 bytes .gradle/7.3.3/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../marsphotos/overview/BindingAdapters.kt | 9 +++ .../marsphotos/overview/OverviewFragment.kt | 4 +- .../marsphotos/overview/PhotoGridAdapter.kt | 60 ++++++++++++------ app/src/main/res/layout/fragment_overview.xml | 2 + 8 files changed, 56 insertions(+), 19 deletions(-) diff --git a/.gradle/7.3.3/executionHistory/executionHistory.lock b/.gradle/7.3.3/executionHistory/executionHistory.lock index 406dc8a79a5616184a22efbc9c745acc62fc1658..87ee22b84ecf8000cc16d86f6a12709df8bc83a0 100644 GIT binary patch literal 17 VcmZRsUgMuDB)xe(0~jzm0{|;d1G)eJ literal 17 VcmZRsUgMuDB)xe(0~jz00RSr<1Bn0t diff --git a/.gradle/7.3.3/fileHashes/fileHashes.bin b/.gradle/7.3.3/fileHashes/fileHashes.bin index e4f133c2ba74b431cd552e1805534daf4635c4a6..59b3b6c5bdd0b21be6e3f2d9b5c57839941d449a 100644 GIT binary patch delta 2671 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 V__w?5U7P+w)kHzmaK8ZA3;@%TN`?Rc delta 1906 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 diff --git a/.gradle/7.3.3/fileHashes/fileHashes.lock b/.gradle/7.3.3/fileHashes/fileHashes.lock index e9193af9913004162df4507be871a28b8c9756a2..feac45b2e42843d655cfd3e47fbf290432b87144 100644 GIT binary patch literal 17 VcmZR6R%ybQyvz0`0~oNI0st^E1QY-O literal 17 VcmZR6R%ybQyvz0`0~oMP0{}3P1atrZ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 06248381ebfc9b73cdba19f7533d23771047cc86..ce5fe84d63582a702286fb0085293ecd4ba9a102 100644 GIT binary patch literal 17 UcmZQBSl$}m?k^O|00x4e04qEMHvj+t literal 17 UcmZQBSl$}m?k^O|00x2!04nMO<p2Nx diff --git a/app/src/main/java/com/example/android/marsphotos/overview/BindingAdapters.kt b/app/src/main/java/com/example/android/marsphotos/overview/BindingAdapters.kt index b4e374e..4d86bb3 100644 --- a/app/src/main/java/com/example/android/marsphotos/overview/BindingAdapters.kt +++ b/app/src/main/java/com/example/android/marsphotos/overview/BindingAdapters.kt @@ -3,8 +3,10 @@ package com.example.android.marsphotos.overview import android.widget.ImageView import androidx.core.net.toUri import androidx.databinding.BindingAdapter +import androidx.recyclerview.widget.RecyclerView import coil.load import com.example.android.marsphotos.R +import com.example.android.marsphotos.network.MarsPhoto @BindingAdapter("imageUrl") fun bindImage(imgView: ImageView, imgUrl: String?) { @@ -17,6 +19,13 @@ fun bindImage(imgView: ImageView, imgUrl: String?) { } } +@BindingAdapter("listData") +fun bindRecyclerView(recyclerView: RecyclerView, + data: List<MarsPhoto>?) { + val adapter = recyclerView.adapter as PhotoGridAdapter + adapter.submitList(data) +} + class BindingAdapters { } diff --git a/app/src/main/java/com/example/android/marsphotos/overview/OverviewFragment.kt b/app/src/main/java/com/example/android/marsphotos/overview/OverviewFragment.kt index 9d0c465..f724968 100644 --- a/app/src/main/java/com/example/android/marsphotos/overview/OverviewFragment.kt +++ b/app/src/main/java/com/example/android/marsphotos/overview/OverviewFragment.kt @@ -37,9 +37,11 @@ class OverviewFragment : Fragment() { * to enable Data Binding to observe LiveData, and sets up the RecyclerView with an adapter. */ override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { + val binding = FragmentOverviewBinding.inflate(inflater) // val binding = GridViewItemBinding.inflate(inflater) @@ -48,7 +50,7 @@ class OverviewFragment : Fragment() { // Giving the binding access to the OverviewViewModel binding.viewModel = viewModel - + binding.photosGrid.adapter = PhotoGridAdapter() return binding.root } } diff --git a/app/src/main/java/com/example/android/marsphotos/overview/PhotoGridAdapter.kt b/app/src/main/java/com/example/android/marsphotos/overview/PhotoGridAdapter.kt index b63d5f4..d0b18fd 100644 --- a/app/src/main/java/com/example/android/marsphotos/overview/PhotoGridAdapter.kt +++ b/app/src/main/java/com/example/android/marsphotos/overview/PhotoGridAdapter.kt @@ -8,28 +8,32 @@ import androidx.recyclerview.widget.RecyclerView import com.example.android.marsphotos.databinding.GridViewItemBinding import com.example.android.marsphotos.network.MarsPhoto -class PhotoGridAdapter : ListAdapter<MarsPhoto, - PhotoGridAdapter.MarsPhotoViewHolder>(MarsPhotoViewHolder) { - class MarsPhotoViewHolder(private var binding: - GridViewItemBinding - ): - RecyclerView.ViewHolder(binding.root) { - fun bind(MarsPhoto: MarsPhoto) { - binding.photo = MarsPhoto +/** + * This class implements a [RecyclerView] [ListAdapter] which uses Data Binding to present [List] + * data, including computing diffs between lists. + */ +class PhotoGridAdapter : + ListAdapter<MarsPhoto, PhotoGridAdapter.MarsPhotosViewHolder>(DiffCallback) { + + /** + * The MarsPhotosViewHolder constructor takes the binding variable from the associated + * GridViewItem, which nicely gives it access to the full [MarsPhoto] information. + */ + class MarsPhotosViewHolder( + private var binding: GridViewItemBinding + ) : RecyclerView.ViewHolder(binding.root) { + fun bind(marsPhoto: MarsPhoto) { + binding.photo = marsPhoto + // This is important, because it forces the data binding to execute immediately, + // which allows the RecyclerView to make the correct view size measurements binding.executePendingBindings() } } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PhotoGridAdapter.MarsPhotoViewHolder { - return MarsPhotoViewHolder(GridViewItemBinding.inflate( - LayoutInflater.from(parent.context))) - } - - override fun onBindViewHolder(holder: PhotoGridAdapter.MarsPhotoViewHolder, position: Int) { - val marsPhoto = getItem(position) - holder.bind(marsPhoto) - } - + /** + * Allows the RecyclerView to determine which items have changed when the [List] of + * [MarsPhoto] has been updated. + */ companion object DiffCallback : DiffUtil.ItemCallback<MarsPhoto>() { override fun areItemsTheSame(oldItem: MarsPhoto, newItem: MarsPhoto): Boolean { return oldItem.id == newItem.id @@ -39,4 +43,24 @@ class PhotoGridAdapter : ListAdapter<MarsPhoto, return oldItem.imgSrcUrl == newItem.imgSrcUrl } } + + /** + * Create new [RecyclerView] item views (invoked by the layout manager) + */ + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): MarsPhotosViewHolder { + return MarsPhotosViewHolder( + GridViewItemBinding.inflate(LayoutInflater.from(parent.context)) + ) + } + + /** + * Replaces the contents of a view (invoked by the layout manager) + */ + override fun onBindViewHolder(holder: MarsPhotosViewHolder, position: Int) { + val marsPhoto = getItem(position) + holder.bind(marsPhoto) + } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_overview.xml b/app/src/main/res/layout/fragment_overview.xml index 2521839..6688d39 100644 --- a/app/src/main/res/layout/fragment_overview.xml +++ b/app/src/main/res/layout/fragment_overview.xml @@ -35,6 +35,8 @@ android:layout_width="0dp" android:layout_height="0dp" android:padding="6dp" + app:listData="@{viewModel.photos}" + android:clipToPadding="false" app:layoutManager= "androidx.recyclerview.widget.GridLayoutManager" app:layout_constraintBottom_toBottomOf="parent" -- GitLab