Setup Android Button programmatically in Kotlin

In this article, we will explore how to set up buttons programmatically in an Android application. We will cover various aspects such as finding buttons by their IDs, setting click listeners, adding or removing buttons dynamically, enabling or disabling buttons, and showing or hiding buttons programmatically. Additionally, we will delve into customizing the background color, borders, and text attributes of buttons using code. By the end of this article, you’ll have a comprehensive understanding of how to manipulate buttons programmatically in your Android projects. Let’s dive in!

Setup Programmatically

Get Button with FindViewById

All views defined in XML layout can be accessed programmatically by calling the findViewById method. You must however give your view, in this case, your button, an identifier, which can later be accessed with the resource bundle R.id. The following code illustrates how a button can be found with the findViewById method.

val button: Button = findViewById(R.id.buttonId)
val button = findViewById<Button>(R.id.buttonId)

Kotlin also provides additional functionality to access views that are defined in XML without calling the findViewById method.

import kotlinx.android.synthetic.main.YOUR_LAYOUT_NAME.<INFLATED_LAYOUT>


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.INFLATED_LAYOUT)
 
    buttonId.text = "Hello Kotlin!"
}
android {
    ...
    buildFeatures {
        viewBinding true
    }
}

Set OnClickListener

In this section, you will also learn how to react to click events on your button. You will see how to handle these events and will give examples of how to make your button clickable or not clickable, or in other words, enabled and disabled.

Android buttons provide an observer object to which you can register OnClickListener or call-back functions. These functions will be executed every time somebody clicks on this widget. If you want to know how the Listener Pattern works, we suggest having look at our detailed tutorial about this design pattern: Observer Pattern.

You can find several examples of how to register and set a listener in our examples below. All you need to make sure of is to have a valid reference to your view.

Add / remove button programmatically

As with any widget, buttons can be added or removed programmatically in Kotlin. All you need is a valid layout, in which the button will be added / removed.

In our example below we have defined 2 buttons and one vertical layout in XML. We get the references to these objects via the findViewById method. The click event handler of the addBtn will declare a new button and insert it at the end of the layout. The removeBtn will get the index of the last button in the layout and (if possible) remove it.

Note that we could derive custom classes from the button base class and completely configure our buttons programmatically.

class MainActivity : AppCompatActivity() {

    var addBtn: Button? = null
    var removeBtn: Button? = null
    var listView: LinearLayout? = null

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

        addBtn = findViewById(R.id.addBtn)
        removeBtn = findViewById(R.id.removeBtn)
        listView = findViewById(R.id.listView)

        addBtn!!.setOnClickListener { addButton() }
        removeBtn!!.setOnClickListener { removeButton() }

    }

    private fun addButton() {
        val newButton = Button(this);
        newButton.text = "New Button: " + listView!!.childCount
        listView!!.addView(newButton)
    }

    private fun removeButton() {
        val lastIndex = listView!!.childCount - 1;
        if(lastIndex < 0) return
        listView!!.removeViewAt(lastIndex)
    }
}
Layout of add / remove button programmatically in Kotlin
Layout with add/remove buttons
Add / remove buttons programmatically in Kotlin
Added dynamically several buttons

Enable / disable button programmatically

Buttons can be enabled or disabled. Enabled widgets will no longer react to click events, while enable widgets will handle such events. In our example, we have declared 2 buttons in the XML layout. We are getting their references with the findViewById function. On the click event listener of, in the enableBtn we are setting the isClickable property of our target button to true. In the disbledBtn we are setting it to false. The extra text view provides information if the button was clicked.

class MainActivity : AppCompatActivity() {

    var enableBtn: Button? = null
    var disableBtn: Button? = null
    var targetBtn: Button? = null
    var infoText: TextView? = null

    var clickCount = 0

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

        enableBtn = findViewById(R.id.enableBtn)
        disableBtn = findViewById(R.id.disableBtn)
        targetBtn = findViewById(R.id.target)
        infoText = findViewById(R.id.infoText)

        enableBtn!!.setOnClickListener { targetBtn!!.isClickable = true }
        disableBtn!!.setOnClickListener { targetBtn!!.isClickable = false }

        targetBtn!!.setOnClickListener { infoText!!.text = "Click count: " + ++clickCount}
    }
}
Layout of enable / disable button programmatically in Kotlin
Layout with enable / disable buttons
Enable / disablebuttons programmatically in Kotlin
Target Button was clicked several times

Show / hide button programmatically

Views in Android can be hidden or shown. Their appearance can be controlled with the visibility property. This property needs an interger which defines their state. The integer value can be accessed via static fields in the View class. The table below shows the current integer representation.

In our example, we have created 3 buttons in XML Layout. We get the references as usual with the findViewById function. The showBtn will set the visibility flag of the targetBtn to View.VISIBLE and the hideBtn to View.INVISIBLE, respectively.

Static FieldConst int Value
View.VISIBLE0
View.INVISIBLE4
class MainActivity : AppCompatActivity() {

    var showBtn: Button? = null
    var hideBtn: Button? = null
    var targetBtn: Button? = null

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

        showBtn = findViewById(R.id.showBtn)
        hideBtn = findViewById(R.id.hideBtn)
        targetBtn = findViewById(R.id.target)

        showBtn!!.setOnClickListener { targetBtn!!.visibility = View.VISIBLE }
        hideBtn!!.setOnClickListener { targetBtn!!.visibility = View.INVISIBLE }
    }
}
layout to show or hide a button in Android
Layout with show/hide buttons
add or hide programmatically an android button in Kotlin
The target Button is currently visible

Background

Android provides functionality to define your background of your button either in XML or programmatically in code.

Background Color

One common use case is to change the default color of an Android button. You can do this either in XML by setting the desired property. The alternative is to get a reference of your button programatically and then set the background color with the setBackgroundColor function of the object. You can get a reference of this object if it is created in XML by using the findViewById method.

Android offers several ways to create colors. We will show you with examples how to create a color from different color codes.

RGB

RGB color codes are the most common representations of colors. Android offers 2 overload functions of Color.rgb(). The first accepts integer values with a range from 0 to 255. The other accepts floating point values in a range from 0 to 1.0. In our example we adapt the red channel of the background color.

RGBA

RGBA or in Android ARGB is just like RGB color codes but with an additional channel for transparency. If you don’t need transparency we recommend using RGB values directly, as RGBA uses more memory. However, you can use this option to create a fully transparent button as shown below.

HEX

An alternative to RGB values is to use directly the HEX color code. You can parse the color object with the function Color.parseColor(string) which accepts the hex color code as shown below.

private fun createButton(red: Int) : Button {

    var button = Button(this);
    button.layoutParams = createParams()
    button.text = "Red: $red"

    var color = Color.rgb(red, 100, 0)
    button.setBackgroundColor(color)
    return button
}
private fun createButton(red: Int) : Button {

    var button = Button(this);
    button.layoutParams = createParams()
    button.text = "Red: $red"

    var color = Color.argb(255, red, 100, 0)
    button.setBackgroundColor(color)
    return button
}
private fun createButton(hex: String = "#646400") : Button {

        var button = Button(this);
        button.layoutParams = createParams()
        button.text = "Hex: $hex"
        var color = Color.parseColor(hex)
        button.setBackgroundColor(color)

        return button
    }

Transparent Background Color

The easiest way to set programmatically a transparent background color is to use an RGBA color, where the alpha channel is 0. This will create a completely transparent color. In the example below you will see the effect of different alpha channels.

private fun createButton(alpha: Int) : Button {

    var button = Button(this);
    button.layoutParams = createParams()
    button.text = "Alpha: $alpha"

    var color = Color.argb(alpha, 0, 200, 100)
    button.setBackgroundColor(color)

    return button
}

Another option is to adapt the alpha channel directly on the Background drawable. The drawable object provides a property alpha which can be set to 0 for full transparency. The result is the same as using RGBA values. This method is the preferred way if you don’t want to create new extra colors.

private fun createButton(alpha: Int) : Button {

    var button = Button(this);
    button.layoutParams = createParams()
    button.text = "Alpha: $alpha"

    var color = Color.rgb(0, 200, 100)
    button.setBackgroundColor(color)
    button.background.alpha = alpha

    return button
}
Background color of Android button, with different red channel or RGB color
Background color of Android button, with different red channel or RGB color
Background color of Android button, with different alpha channel or ARGB color
Background color of Android button, with different alpha channel or ARGB color

Border

Defining the border of a button in Android can be quite a challenge. Especially if you want or need to do it programmatically. To setup correctly your border, you first need to have a reference to your button. You can either find an existing button, which is defined in XML Layout with the findViewById function or you can create a new one directly in your Kotlin code.

Afterward you need to define manually the background. The background property accepts a Drawable object. You can create a new one or use existing ones from the Android ecosystem.

Set Border Width programmatically

As an example how to set the border width programmatically in code, you can use a ShapeDrawable. In our example, we use such a drawable with an actual rectangle shape. The drawable exposes a paint instance that finally exposes properties to change border width. The property to set the border width programmatically is the strokeWidth property on the paint instance.

In the code example below we have created a linear layout in XML. In Kotlin code we reference (by findViewById) and it in a for-loop 5 buttons. Each button has a different border width. The result can be seen in the next image.

class MainActivity : AppCompatActivity() {

    var listView: LinearLayout? = null

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

        listView = findViewById(R.id.layout)

        for (strokeWidth in 1..5) {
            listView!!.addView(createButton(strokeWidth * 10))
        }
    }

    private fun createButton(borderWidth: Int) : Button {

        var button = Button(this);
        button.layoutParams = createParams()
        button.background = createBorderBackground(borderWidth)
        button.text = "BorderWidth: $borderWidth"

        return button
    }
    
    private fun createParams() : ViewGroup.LayoutParams {
        var left = 100
        var right = 100
        var top = 20
        var bottom = 20

        val params = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        )
        params.setMargins(left, top, right, bottom)
        return params
    }

    private fun createBorderBackground(borderWidth: Int) : Drawable {
        val shapeDrawable = ShapeDrawable()
        shapeDrawable.shape = RectShape()
        shapeDrawable.paint.color = Color.BLACK
        shapeDrawable.paint.style = Paint.Style.STROKE
        shapeDrawable.paint.strokeWidth = borderWidth.toFloat();

        return shapeDrawable
    }
}

Set Border Radius / Corner Radius programmatically

Similar to the border width, the border-radius can be programmatically defined. This is the use case to create round corners. First, you need as well access to the correct drawable, which will be the background of our button. In this case, we are using a GradientDrawable, as it exposes the property cornerRadius property. Similar to the previous code we are creating several views and modifying the border-radius programmatically. The result can be seen in the next image.

class MainActivity : AppCompatActivity() {

    var listView: LinearLayout? = null

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

        listView = findViewById(R.id.layout)

        for (borderRadius in 1..5) {
            listView!!.addView(createButton(borderRadius * 10))
        }
    }

    private fun createButton(borderRadius: Int) : Button {

        var button = Button(this);
        button.layoutParams = createParams()
        button.background = createBorderBackground(borderRadius)
        button.text = "BorderRadius: $borderRadius"


        return button
    }

    private fun createParams() : ViewGroup.LayoutParams {
        var left = 100
        var right = 100
        var top = 20
        var bottom = 20

        val params = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        )
        params.setMargins(left, top, right, bottom)
        return params
    }

    private fun createBorderBackground(borderRadius: Int) : Drawable {

        var gradientDrawable = GradientDrawable()
        gradientDrawable.cornerRadius = borderRadius.toFloat()
        gradientDrawable.setColor(Color.LTGRAY)

        return gradientDrawable
    }
}
Android button with variable border width
Button with variable border width
Android button with variable corner radius
Button with variable corner radius
Android button with variable border color
Button with variable border color

Set Border Color programmatically

The border color of an Android button can be programmatically modified just like the border width. You can use a ShapeDrawable as it exposes the paint instance. On the paint instance, you can set the color directly on the property.

class MainActivity : AppCompatActivity() {

    var listView: LinearLayout? = null

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

        listView = findViewById(R.id.layout)

        for (strokeWidth in 1..5) {
            listView!!.addView(createButton(strokeWidth * 50))
        }
    }

    private fun createButton(red: Int) : Button {

        var button = Button(this);
        button.layoutParams = createParams()
        button.background = createBorderBackground(red)
        button.text = "Red: $red"

        return button
    }

    private fun createParams() : ViewGroup.LayoutParams {
        var left = 100
        var right = 100
        var top = 20
        var bottom = 20

        val params = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT
        )
        params.setMargins(left, top, right, bottom)
        return params
    }

    private fun createBorderBackground(red: Int) : Drawable {

        val shapeDrawable = ShapeDrawable()
        shapeDrawable.shape = RectShape()
        shapeDrawable.paint.color = Color.rgb(red, 100, 0)
        shapeDrawable.paint.style = Paint.Style.STROKE
        shapeDrawable.paint.strokeWidth = 20.0f

        return shapeDrawable
    }
}

Text

The button instance provides several functions to change its properties. In the following step, we will provide some examples of how to change the most common attributes of an Android button.

The most obvious one is of course how to change the text. You can see this in most of the examples on this page. Just set the desired text with the property access text. Of course, you can use as well the setText function. The same property can be used if you want to get the current button text.

Set Text Color programmatically

The text color is as well easy to be changed once you have the instance of your button. You can call the setTextColor function to set the desired color to your button. In the code below, we use the same setup as in the previous example. For every step in the for-loop, we increase the red part of the RGB color. You can see the result in the image below. The setTextColor function can be used to see the button text color programmatically.

private fun createButton(red: Int) : Button {

    var button = Button(this);
    button.layoutParams = createParams()
    button.text = "Red: $red"
    button.setTextColor(Color.rgb(red, 100, 0))

    return button
}

private fun createParams() : ViewGroup.LayoutParams {
    var left = 100
    var right = 100
    var top = 20
    var bottom = 20

    val params = ConstraintLayout.LayoutParams(
        ConstraintLayout.LayoutParams.MATCH_PARENT,
        ConstraintLayout.LayoutParams.WRAP_CONTENT
    )

    params.setMargins(left, top, right, bottom)
    return params
}

Android button with variable text color
Android button with variable text color
Android button with variable font size
Android button with variable font size

Set Text Size / Font Size programmatically

The following code snipped illustrates how to change the fontsize of the button text programmatically. It uses the same setup as in the previous example. In every loop, the size is increased and set to the new button. The result can be seen in the previous image.

private fun createButton(size: Int) : Button {

    var button = Button(this);
    button.layoutParams = createParams()
    button.text = "Size: $size"
    button.textSize = size.toFloat()

    return button
}