diff --git a/.gradle/7.3.3/executionHistory/executionHistory.lock b/.gradle/7.3.3/executionHistory/executionHistory.lock index 406dc8a79a5616184a22efbc9c745acc62fc1658..87ee22b84ecf8000cc16d86f6a12709df8bc83a0 100644 Binary files a/.gradle/7.3.3/executionHistory/executionHistory.lock and b/.gradle/7.3.3/executionHistory/executionHistory.lock differ diff --git a/.gradle/7.3.3/fileHashes/fileHashes.bin b/.gradle/7.3.3/fileHashes/fileHashes.bin index e4f133c2ba74b431cd552e1805534daf4635c4a6..59b3b6c5bdd0b21be6e3f2d9b5c57839941d449a 100644 Binary files a/.gradle/7.3.3/fileHashes/fileHashes.bin and b/.gradle/7.3.3/fileHashes/fileHashes.bin differ diff --git a/.gradle/7.3.3/fileHashes/fileHashes.lock b/.gradle/7.3.3/fileHashes/fileHashes.lock index e9193af9913004162df4507be871a28b8c9756a2..feac45b2e42843d655cfd3e47fbf290432b87144 100644 Binary files a/.gradle/7.3.3/fileHashes/fileHashes.lock and b/.gradle/7.3.3/fileHashes/fileHashes.lock differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 06248381ebfc9b73cdba19f7533d23771047cc86..ce5fe84d63582a702286fb0085293ecd4ba9a102 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ 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 b4e374e1cfce7bb5e7a6493a69e5fd2435ed029c..4d86bb34d92f16ddd2eaa672fd0fa710bee748b0 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 9d0c465bd9f2f44bd972a92483f52bd56f9acfbd..f72496863dabc60291e142e9e0f7e58d7b604c30 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 b63d5f4379d249dfe158f7c902be301d1baa18f3..d0b18fd6337aca92c4dfb02690fc6448560dfc4d 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 252183982a445034710dfda7406d77b283f6b8e2..6688d398ccd67bd08576df29bc384ef44dde6d94 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"