Kotlin: Dynamically Creating an ImageView During Runtime

Andrew Fenner
5 min readDec 28, 2017

--

Let’s suppose you have a view that you don’t need to render until some event has occurred during runtime.

Let’s also suppose that you may also want to create multiple instances of this view without having to manually add them to your xml file.

Simple enough, right?

Note: If you are familiar with this concept already and would just like to see the example code, skip to the bottom. Otherwise, keep reading and I’ll take you through the whole thing.

Let’s get started:

First, go ahead and fire up Android studio and create a new project. Be sure to check “Include Kotlin Support” on the dialog where you name your project.

To make this simple, just choose the “empty activity” option.

Next, navigate to your xml file and you’ll see the following code:

Android is nice enough to create a little TextBox with “hello world” just to show how things work. We won’t be needing it so just replace the TextView tag with the following code:

<Button
android:id="@+id/creatorButton"
android:text="Create Something"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

This should create a small button in the upper left hand corner like so:

Button we’ll use to create our views.

You’ll notice from the xml code that this button has an id assigned to it:

android:id="@+id/creatorButton"

Now here’s where things get fun. Most Java tutorials require you to call getViewById(R.id.creatorButton) from your main activity in order to start using the button your declared in xml — not Kotlin.

In Kotlin, we can access our button from our main activity just by using it’s id alone.

Which means that this…

var creatorButton = findViewById(R.id.creatorButton)

…is completely unnecessary.

Thus, we can reference our creatorButton directly and go straight to setting the clickListener inside our onCreate function like so:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_shapes_view)


creatorButton.setOnClickListener {
// This is where we'll dynamically create our new view!!! }

}

Now let’s take a step back and look at how this all has to come together. In order to get another view up and running I need a few things:

  1. Declare and Initialize the new ImageViee
  2. Add it to the view
  3. Give it some style.

There are a few ways to declare objects in Kotlin. For now, just add the following code inside your onClickListener function:

var newView: ImageView

newView = ImageView(this)

This declares a new view called newView and type casts it as an ImageView Then, it initializes a new ImageView by passing “this” to the image view’s constructor.

Now comes the part where we have to add our ImageView to our layout. What layout? Our ConstraintLayout defined in the xml file where we added our first Button:

Oh No! Unlike our Button, the ConstraintLayout has no id! How are we going to reference it if we don’t know what it’s called?

Let’s give it a name, say…”myLayout” by adding the following line of code to the ConstraintLayout header tag.

android:id="@+id/myLayout"

Should look like this:

Perfect! Now we can go back to our main activity and start adding views to our ConstraintLayout dynamically!

Go back to your onClick listener and add the line:

myLayout.addView(newView)

directly after the new button your declared.

Now your onClickListener should look like this:


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_shapes_view)


creatorButton.setOnClickListener {
var newView: ImageView

newView = ImageView(this)
myLayout.addView(newView)}

}

Now let’s make sure our view has a bit of style so that we can actually tell that it has been created.

To make things simple, we’ll just set the background color to Magenta and place it at some random point on the canvas.

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_shapes_view)


creatorButton.setOnClickListener {
var newView: ImageView

newView = ImageView(this)
myLayout.addView(newView) newView.layoutParams.height = 200
newView.layoutParams.width = 200
newView.x = 300F
newView.y = 500F
newView.setBackgroundColor(Color.MAGENTA)
}

}

Now lets run it:

There you have it! An ImageView rendered dynamically during run time!

Stop.

Wait a minute.

The ImageView I created was declared within my onCreate function within clickListener. I have no reference to it outside the scope of that function.

No worries! Just declare your ImageView outside of onCreate using lateinit. This lets our app know that we are going to use an ImageView throughout our main activity, but we won’t initialize it until later.

Now you have a reference to your image view from anywhere within your MainActivity and can manipulate it anyway you like. Be careful, if you don’t use “lateinit” you will get a null pointer exception error.

I hope this saved you some much needed time. I’m a Swift game developer and this is actually my first Android tutorial. Clap or comment or both.

--

--