How to create a bitmap adapter and display it in ImageView

69 views Asked by At

I'm a beginner in Kotlin and Android Studio and I would like to request for help to resolve this question:

  1. Download an image from the URL;
  2. Create Adapter module to receive bitmap;
  3. Show image through ImageView object

  1. I managed to resolve the first item with this simpler method. The next step is to improve with some library, but it's working.
private fun downloadImage(item: Item) = Thread {

        val imageConnection = URL(imageItem.url).openConnection() as HttpURLConnection

        try {
            if (photosConnection.responseCode == HTTP_OK) {
                runOnUiThread {
                    val bitmap = BitmapFactory.decodeStream(photosConnection.inputStream)
                    activityMainBinding.objImageView.apply {
                    // Implementar o novo Adapter                    
                    }
                }
            } else {
                runOnUiThread{
                    Toast.makeText(this, " Deu erro !!!", Toast.LENGTH_SHORT).show()
                }
            }
        } catch ( e: Exception)  {
                e.printStackTrace()
        } finally {
            imageConnection.disconnect()
        }
    }.start()
  1. Create adapter module

I tried to make this adapter which is what I had as a reference. But inheriting from ArrayAdapter I understood that not compatible with Bitmap type. I was also unsure about the object (android.R.layout) normally I use (android.R.layout.simple_list_item_1)when they are String list applications. But in this case I didn't find similar, for example (android.R.layout.image).

class ImageAdapter (
    private val activityContext: Context,
    private val imageList: MutableList<Bitmap>
): ArrayAdapter<Bitmap>(activityContext, android.R.layout.simple_list_item_1, photosList) {


    private data class ImageHolder( val imageVw: ImageView )

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {

        val imageView = convertView ?: LayoutInflater.from(activityContext)
                .inflate(android.R.layout.simple_list_item_1,parent,false).apply {
                tag = ImageHolder(findViewById(android.R.id.text1))
                }

        (imageView.tag as ImageHolder)imageVw.setImageBitmap = imageList[position]

        return imageView
    }

}

I appreciate any help

1

There are 1 answers

1
Miroslav Hýbler On BEST ANSWER

I'll try to keep it simple as possible

  1. Use library to download image, e.g. glide, it's really simple and handling all the other things like url connection, thread and caching image.

  2. For this you should use RecyclerView with creating your subclass of RecyclerView.Adapter.

  3. Also done with the glide library.

Now for code, this is Activity layout, you have to put recyclerView somewhere to show the list with images, in my example activity_image_adapter.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".simpleimageAdapter.ImageAdapterActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recyclerView"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:itemCount="4"
        tools:listitem="@layout/item_image"/>

</FrameLayout>

And also create layout for image items, in my exampe item_image.xml

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/itemImageView"
    android:layout_width="match_parent"
    android:layout_height="256dp"
    android:importantForAccessibility="no"
    android:scaleType="centerCrop"/>

Next step you need to create custom adapter for the recyclerView:

class ImageAdapter : RecyclerView.Adapter<ImageAdapter.ImageViewHolder>() {

//Data list for the adapter, we will set data later
private var images: List<ImageItem> = emptyList()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageViewHolder {
    //Creates view holder which holds view. Recycler is reusing views because of performance
    val inflater = LayoutInflater.from(parent.context)
    //Create view and attach it to the parent
    val view = inflater.inflate(R.layout.item_image, parent, false)
    return ImageViewHolder(view)
}

override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
    //Called to show data with holder
    holder.onBind(item = images[position])
}

override fun getItemCount(): Int {
    //Returns items count this adapter shows
    return images.size
}


fun setData(list: List<ImageItem>) {
    this.images = list
    //Set new dataset for adapter and notify it about change
    //notifyDataSetChanged isn't the best option but for now let's keep it simple
    notifyDataSetChanged()
}


inner class ImageViewHolder(contentView: View) : RecyclerView.ViewHolder(contentView) {
    
    private val imageView: ImageView = contentView.findViewById(R.id.itemImageView)
    
    fun onBind(item: ImageItem) {
        //Load image with glide library and show it with imageView
        Glide.with(imageView.context)
            .load(item.url)
            .centerCrop()
            .into(imageView)
    }
}
}

Now put it all together in activity code:

class ImageAdapterActivity : AppCompatActivity() {


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_image_adapter)


    //Just simple data for the example
    val data = listOf(
        ImageItem(url = "https://static.vecteezy.com/system/resources/thumbnails/025/284/015/small_2x/close-up-growing-beautiful-forest-in-glass-ball-and-flying-butterflies-in-nature-outdoors-spring-season-concept-generative-ai-photo.jpg"),
        ImageItem(url = "https://i0.wp.com/picjumbo.com/wp-content/uploads/beautiful-nature-mountain-scenery-with-flowers-free-photo.jpg?w=600&quality=80"),
        ImageItem(url = "https://media.istockphoto.com/id/517188688/photo/mountain-landscape.jpg?s=612x612&w=0&k=20&c=A63koPKaCyIwQWOTFBRWXj_PwCrR4cEoOw2S9Q7yVl8=")
    )

    val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
    val imageAdapter = ImageAdapter()
    //Set adapter to the recycler
    recyclerView.adapter = imageAdapter

    //Set data to adapter
    imageAdapter.setData(list = data)
}
}

After complete all part you will be able to show images, e.g like in the picture enter image description here