Android Kotlin: How to set an image in an ImageView using a URI

Introduction

This Android Kotlin example demonstrates how to set an image in an ImageView using a URI from the app's resources, specifically a drawable resource. It also shows how to clear the previous image cache before setting a new image. This functionality can be useful when dealing with dynamic content, such as images loaded from external sources or dynamically assigned resources. By leveraging Kotlin's extension functions and Android’s built-in URI handling, the example provides an efficient way to handle image rendering in an Android application.

MainActivity Overview

The MainActivity class extends AppCompatActivity and serves as the entry point of the application. Within the onCreate() method, the layout activity_main is set as the content view, which contains an ImageView and a TextView. The main focus of this code is to retrieve a drawable resource as a URI and use it to set the image in the ImageView.

The method applicationContext.drawableToUri() is called to convert a drawable resource (R.drawable.tulip) into a Uri object. This is accomplished by using an extension function that constructs the URI string in the android.resource:// format, which is recognized by the Android system for resources.

Image Handling Logic

Before setting the image in the ImageView, the existing image is cleared by passing null to the setImageURI() method. This step ensures that any cached image is removed, and the view is prepared for a new image to be loaded. This is particularly important when dealing with image sources that may change, such as when users select different images from their device or from the web.

After clearing the cache, the new image is set using the Uri object. The setImageURI() method assigns the image to the ImageView from the given URI. This approach abstracts away the complexity of dealing with different resource types (drawables, external URIs, etc.) by unifying image loading into a single call.

Extension Function: drawableToUri()

The drawableToUri() function is an extension of the Context class and converts a drawable resource ID into a Uri. It constructs a URI string in the format android.resource://package_name/resource_id. This format is required by Android to reference resources stored within the app’s res directory, such as drawables, strings, or layouts. The function returns a Uri object that can then be passed to ImageView.setImageURI() to load the corresponding image.

This extension function demonstrates how Kotlin can enhance code reusability and readability. By adding this function directly to the Context class, you can call drawableToUri() from any context within the app, making it a flexible and reusable utility.

Layout Description

The activity_main.xml layout file defines the user interface for the activity. It uses a ConstraintLayout to arrange the ImageView and TextView. The ImageView is set to have a height of 300dp and a width that stretches to the parent’s width. This allows the image to be displayed clearly at the top of the screen. The TextView, located directly below the ImageView, is used to display the URI of the image, providing feedback to the user about which image has been loaded.

Summary

In summary, this Android Kotlin example provides a straightforward implementation of setting an image from a URI into an ImageView using an extension function to convert drawable resources into URIs. The use of setImageURI(null) ensures that previous images are cleared before loading a new one, preventing potential caching issues. The drawableToUri() extension function enhances code maintainability and reuse, allowing simple access to URI representations of drawables throughout the application. This pattern can be extended to handle more complex image sources, such as those fetched from the internet or selected from a gallery.


MainActivity.kt

package com.example.jetpack

import android.content.Context
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

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

        // get uri from drawable
        val uri = applicationContext.drawableToUri(R.drawable.tulip)

        // remove previous image uri cache
        imageView.setImageURI(null)

        // set image view image from uri
        imageView.setImageURI(uri)

        // show the uri in text view
        textView.text = uri.toString()
    }
}


// extension function to get uri from drawable
fun Context.drawableToUri(drawable: Int):Uri{
    return Uri.parse("android.resource://$packageName/$drawable")
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#EDEAE0"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="300dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:fontFamily="sans-serif-condensed"
        android:gravity="center"
        android:padding="8dp"
        android:textColor="#0014A8"
        android:textSize="25sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView"
        tools:text="TextView" />

</androidx.constraintlayout.widget.ConstraintLayout>
More android kotlin tutorials