Wednesday, July 29, 2020

android kotlin - RadioButton with image and text

MainActivity.kt

package com.example.jetpack

import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.text.style.DynamicDrawableSpan
import android.widget.RadioButton
import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.set
import androidx.core.text.toSpannable
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

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

        // set radio buttons icon and text programmatically
        setRadioImageText(radioNormal,
            R.drawable.ic_text_format,"  Normal text")
        setRadioImageText(radioBold,
            R.drawable.ic_format_bold,"  Bold text")
        setRadioImageText(radioItalic,
            R.drawable.ic_format_italic,"  Italic text")
        setRadioImageText(radioUnderline,
            R.drawable.ic_format_underlined,"  Underlined text")
        setRadioImageText(radioStrikethrough,
            R.drawable.ic_format_striketrough,"  Strike through text")

        // radio group checked change listener
        radioGroup.setOnCheckedChangeListener { radioGroup, i ->
            // get the radio group checked radio button
            findViewById<RadioButton>(i)?.apply {
                // show the checked radio button's text in text view
                textView2.text = text.removeRange(0..1)
            }
        }
    }
}


// extension function to programmatically show image and text in radio button
fun Context.setRadioImageText(
    radioButton: RadioButton,
    drawableId: Int,
    text: String
){
    // make the text spannable
    val spannable = text.toSpannable()

    // dynamic drawable span from drawable resource
    spannable[0..1] = object : DynamicDrawableSpan(){
        override fun getDrawable(): Drawable? {
            val drawable: Drawable? = getDrawable(drawableId)
            drawable?.setBounds(
                0,
                0,
                drawable.intrinsicWidth,
                drawable.intrinsicHeight
            )
            return drawable
        }
    }

    // finally, show image and text in radio button
    radioButton.text = spannable
}
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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="#E5E4E2">

    <TextView
        android:id="@+id/textView"
        style="@style/TextAppearance.MaterialComponents.Headline6"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:padding="8dp"
        android:text="Select any one text style."
        android:typeface="monospace"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="2dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView">

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/radioNormal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Normal" />

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/radioBold"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Bold" />

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/radioItalic"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Italic" />

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/radioUnderline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Underline" />

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/radioStrikethrough"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Strike through" />

    </RadioGroup>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:textColor="#32174D"
        android:textSize="30sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/radioGroup"
        tools:text="TextView" />

</androidx.constraintlayout.widget.ConstraintLayout>
build.gradle(app) [code to add]

android {
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }
}

dependencies {
    // android ktx
    implementation 'androidx.core:core-ktx:1.3.1'
}