Preparing RecyclerView to Display Images

The current PhotoHolder in PhotoGalleryFragment simply provides TextViews for the RecyclerView’s GridLayoutManager to display. Each TextView displays the caption of a GalleryItem.

To display photos, you are going to update PhotoHolder to provide ImageViews instead. Eventually, each ImageView will display a photo downloaded from the url of a GalleryItem.

Start by creating a new layout file for your gallery items called list_item_gallery.xml. This layout will consist of a single ImageView (Listing 25.1).

Listing 25.1  Gallery item layout (res/layout/list_item_gallery.xml)

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="match_parent"
           android:layout_height="120dp"
           android:layout_gravity="center"
           android:scaleType="centerCrop"/>

These ImageViews will be managed by RecyclerView’s GridLayoutManager, which means that their width will vary. Their height, on the other hand, will remain fixed. To make the most of the ImageView’s space, you have set its scaleType to centerCrop. This setting centers the image and then scales it up so that the smaller dimension is equal to the view and the larger one is cropped on both sides.

Next, update PhotoHolder to hold an ImageView instead of a TextView. Replace bindTitle with a function reference to set the ImageView’s Drawable.

Listing 25.2  Updating PhotoHolder (PhotoGalleryFragment.kt)

class PhotoGalleryFragment : Fragment() {
    ...
    private class PhotoHolder(private val itemTextView: TextView)
        : RecyclerView.ViewHolder(itemTextView) {
    private class PhotoHolder(private val itemImageView: ImageView)
        : RecyclerView.ViewHolder(itemImageView) {

        val bindTitle: (CharSequence) -> Unit = itemTextView::setText
        val bindDrawable: (Drawable) -> Unit  = itemImageView::setImageDrawable
  }
  ...
}

Previously, the PhotoHolder constructor assumed it would be passed a TextView. The new version instead expects an ImageView.

Update PhotoAdapter’s onCreateViewHolder(…) to inflate the list_item_gallery.xml file you created and pass it to PhotoHolder’s constructor. Add the inner keyword so PhotoAdapter can access the parent activity’s layoutInflater property directly. (You could get the inflater from parent.context, but you will need access to other properties and functions in the parent activity later, and using inner makes that easier.)

Listing 25.3  Updating PhotoAdapter’s onCreateViewHolder(…) (PhotoGalleryFragment.kt)

class PhotoGalleryFragment : Fragment() {
    ...
    private inner class PhotoAdapter(private val galleryItems: List<GalleryItem>)
        : RecyclerView.Adapter<PhotoHolder>() {

        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): PhotoHolder {
            val textView = TextView(activity)
            return PhotoHolder(textView)
            val view = layoutInflater.inflate(
                R.layout.list_item_gallery,
                parent,
                false
            ) as ImageView
            return PhotoHolder(view)
        }
        ...
    }
    ...
}

Next, you will need a placeholder image for each ImageView to display until you download an image to replace it. Find bill_up_close.png in the solutions file (www.bignerdranch.com/​solutions/​AndroidProgramming4e.zip) and put it in res/drawable.

Update PhotoAdapter’s onBindViewHolder(…) to set the placeholder image as the ImageView’s Drawable.

Listing 25.4  Binding the default image (PhotoGalleryFragment.kt)

class PhotoGalleryFragment : Fragment() {
    ...
    private inner class PhotoAdapter(private val galleryItems: List<GalleryItem>)
        : RecyclerView.Adapter<PhotoHolder>() {
        ...
        override fun onBindViewHolder(holder: PhotoHolder, position: Int) {
            val galleryItem = galleryItems[position]
            holder.bindTitle(galleryItem.title)
            val placeholder: Drawable = ContextCompat.getDrawable(
                requireContext(),
                R.drawable.bill_up_close
            ) ?: ColorDrawable()
            holder.bindDrawable(placeholder)
        }
    }
    ...
}

Notice that you are providing a blank ColorDrawable object if ContextCompat.getDrawable(…) returns null.

Run PhotoGallery, and you should see an array of close-up Bills, as in Figure 25.1.

Figure 25.1  A Billsplosion

A Billsplosion
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.55.55.239