In this tutorial, we’ll be discussing and implementing RadioButton and RadioGroups in our Android Application using Kotlin.
A RadioButton is a widget which can be set to checked or an unchecked state. Once a RadioButton is checked you cannot uncheck it unless it’s present inside a RadioGroup.
A RadioGroup is a container that holds RadioButtons. At a time inside a RadioGroup, only one RadioButton can be set as checked.
A RadioButton is defined in the xml in the following manner:
1 2 3 4 5 6 7 8 9 |
<RadioButton android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:onClick="androidlyRadioButton" android:text="Androidly RadioButtons" android:textSize="18sp" /> |
android:text
is used to set the text of the RadioButton.
You can set the text gravity using the android:gravity
attribute
android:onClick
is used to set the function in the Kotlin activity to be triggered when the RadioButton is clicked.
android:buttonTint
is used to set the color of the circular button. By default, it is set to the colorAccent specified in the styles.xml.
To define a RadioButton programmatically we use:
1 2 3 |
val radioButton = RadioButton(this) |
A RadioGroup is defined in the following way in the XML.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<RadioGroup android:layout_width="match_parent" android:layout_height="wrap_content" android:contentDescription="Layouts" android:orientation="vertical"> <RadioButton android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:onClick="androidlyRadioButton" android:text="Androidly RadioButtons" android:textSize="18sp" /> . . . . </RadioGroup> |
Setting the orientation on the RadioGroup would lay the RadioButtons in that order(horizontally/vertically).
To define a RadioGroup programmatically, we do:
1 2 3 4 5 |
val radioButton = RadioButton(this) val radioGroup = RadioGroup(this) radioGroup.addView(radioButton) |
This adds a single RadioButton inside the RadioGroup.
A RadioGroup can set Layout Weights similar to a LinearLayout.
We use the attribute android:weightSum
on the RadioGroup and android:layout_weight
on the RadioButton(s).
To clear ALL states from a RadioGroup we need to invoke the following in our Kotlin Activity class.
1 2 3 |
radioGroup.clearCheck() |
RadioGroup Listener
In our activity, we can use the RadioGroup.OnCheckChangedListener
interface callback to listen for changes in the states of the RadioButtons
held inside the RadioGroup
.
1 2 3 4 5 |
radioGroup.setOnCheckedChangeListener(RadioGroup.OnCheckedChangeListener { radioGroup, i -> textView.text = "option "+i+" is selected" }) |
radioGroup argument is the current radiogroup and i is the id of the RadioButton present in that RadioGroup.
In the following section, we’ll be creating a Single View Application that hosts RadioGroups from the XML as well as programmatically. We’ll display a Toast whenever any of the RadioButtons is checked.
Project Structure
Layout Code
The code for the activity_main.xml layout is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:id="@+id/androidlyRadioButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:onClick="androidlyRadioButton" android:text="Androidly RadioButtons" android:textSize="18sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="Which layout has child views on top of each other?" android:textSize="20sp" /> <RadioGroup android:id="@+id/firstRg" android:layout_width="match_parent" android:layout_height="wrap_content" android:contentDescription="Layouts" android:orientation="vertical"> <RadioButton android:id="@+id/radioButton1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="LinearLayout" android:textSize="18sp" /> <RadioButton android:id="@+id/radioButton2" android:layout_width="match_parent" android:layout_height="wrap_content" android:buttonTint="@color/colorPrimary" android:text="RelativeLayout" android:textSize="18sp" /> <RadioButton android:id="@+id/radioButton3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="FrameLayout" android:textColor="#99cc00" android:textSize="18sp" /> <RadioButton android:id="@+id/radioButton4" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="TableLayout" android:textSize="18sp" /> </RadioGroup> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="Which of the following are clickable?" android:textSize="20sp" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear Groups" /> </LinearLayout> |
Activity Code
The code for the MainActivity.kt class is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package net.androidly.androidlyradiobuttons import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.view.View import android.widget.* import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.view.* class MainActivity : AppCompatActivity(), RadioGroup.OnCheckedChangeListener { val buttonTexts = arrayListOf("Buttons", "Text", "Both") val ID = 101 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val secondRg = RadioGroup(this) secondRg.orientation = RadioGroup.HORIZONTAL secondRg.weightSum = 3f secondRg.id = ID secondRg.contentDescription = "Widgets" secondRg.setOnCheckedChangeListener(this) linearLayout.firstRg.setOnCheckedChangeListener(this) val p = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT) p.weight = 0.5f for (i in 0 until buttonTexts.size) { val radioButton = RadioButton(this) radioButton.apply { text = buttonTexts[i] id = i layoutParams = p } secondRg.addView(radioButton) } linearLayout.addView(secondRg, 4) button.setOnClickListener { secondRg.clearCheck() linearLayout.firstRg.clearCheck() } } override fun onCheckedChanged(group: RadioGroup?, checkId: Int) { val checkedRadioButton = group?.findViewById(group.checkedRadioButtonId) as? RadioButton checkedRadioButton?.let { if (checkedRadioButton.isChecked) Toast.makeText(applicationContext, "RadioGroup: ${group?.contentDescription} RadioButton: ${checkedRadioButton?.text}", Toast.LENGTH_LONG).show() } } fun androidlyRadioButton(view: View) { val radioButton = view as RadioButton Toast.makeText(applicationContext, "Radio Button: ${radioButton.text}", Toast.LENGTH_LONG).show() } } |
In the above code, we’ve created a Second RadioGroup which holds the RadioButtons horizontally.
We’ve implemented RadioGroup.OnCheckedChangeListener
interface on our Activity.
androidlyRadioButton is triggered when the single RadioButton defined in the layout gets checked.
We need to typecast it from View to RadioButton.
fun onCheckedChanged(group: RadioGroup?, checkId: Int)
is what gets triggered everytime a RadioButton from any of the RadioGroups gets checked or unchecked.
checkedRadioButtonId
property is used to get the ID of the RadioButton that was selected.
We use the isChecked
property on the RadioButton to display a Toast only when a RadioButton gets checked.
The output of the above application in action is given below:
This brings an end to this tutorial. You can download the AndroidlyRadioButtons Project from the link below.