Skip to content

Instantly share code, notes, and snippets.

@avisper
Last active December 11, 2019 08:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avisper/4a7da16294add0a96a722f6a97c0a5cd to your computer and use it in GitHub Desktop.
Save avisper/4a7da16294add0a96a722f6a97c0a5cd to your computer and use it in GitHub Desktop.
MixedCompoundButtonGroup resolve the one and only selected button in CompoundButton (CheckBox, RadioButton, Switch, ToggleButton) group
<?xml version="1.0" encoding="utf-8"?>
<your.project.package.MixedCompoundButtonGroup xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/mixedCompoundButtonGroup_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:id="@+id/rb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="aaa"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RadioButton
android:id="@+id/rb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bbb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RadioButton
android:id="@+id/rb3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ccc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rb1" />
<LinearLayout
android:id="@+id/ll_radioGroup_container1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toggleButton">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="AAA" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="BBB" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="CCC" />
</LinearLayout>
<Switch
android:id="@+id/btn_switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/rb1" />
<ToggleButton
android:id="@+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/btn_switch1" />
</your.project.package.MixedCompoundButtonGroup>
package your.project.package
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.CompoundButton
import android.widget.Toast
import your.project.package.R
class CompoundButtonGroupActivity : AppCompatActivity() {
private lateinit var mixedCompoundButtonGroup: MixedCompoundButtonGroup
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_compound_button_group)
mixedCompoundButtonGroup = findViewById(R.id.mixedCompoundButtonGroup_container)
mixedCompoundButtonGroup.setOnCheckedChangeListener(object : OnCheckedChangeListener {
override fun onCheckedChanged(compoundButton: CompoundButton) {
Toast.makeText(applicationContext, "checkedId = ${compoundButton.id}", Toast.LENGTH_SHORT).show()
}
})
}
override fun onDestroy() {
mixedCompoundButtonGroup.setOnCheckedChangeListener(null)
super.onDestroy()
}
}
package your.project.package
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.RadioGroup
import androidx.constraintlayout.widget.ConstraintLayout
/**
* Created by Avishay.Peretz on 10/12/2019.
*/
class MixedCompoundButtonGroup @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private var currentCompoundButton: CompoundButton? = null
private lateinit var compoundButtonCheckedChangedListener: CompoundButton.OnCheckedChangeListener
private var checkedChangedListener: OnCheckedChangeListener? = null
init {
initCompoundButtonListener()
}
private fun initCompoundButtonListener() {
compoundButtonCheckedChangedListener = CompoundButton.OnCheckedChangeListener { compoundButton, isChecked ->
setChecked(compoundButton, isChecked)
}
}
private fun setChecked(compoundButton: CompoundButton, isChecked: Boolean) {
if (isChecked.not()) return
if (currentCompoundButton != null) {
currentCompoundButton!!.isChecked = false
currentCompoundButton = compoundButton
} else {
currentCompoundButton = compoundButton
}
checkedChangedListener?.onCheckedChanged(currentCompoundButton!!)
}
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
super.addView(child, index, params)
setCompoundButtonListener(child)
}
private fun setCompoundButtonListener(view: View?) {
if (view == null) return
if (view is CompoundButton) {
view.setOnCheckedChangeListener(compoundButtonCheckedChangedListener)
} else if (view is ViewGroup && view !is RadioGroup) { // NOT RadioGroup!
for (i in 0 until view.childCount) {
setCompoundButtonListener(view.getChildAt(i))
}
}
}
fun setOnCheckedChangeListener(onCheckedChangeListener: OnCheckedChangeListener?) {
checkedChangedListener = onCheckedChangeListener
}
}
interface OnCheckedChangeListener {
fun onCheckedChanged(compoundButton: CompoundButton)
}
@avisper
Copy link
Author

avisper commented Dec 10, 2019

#Android #Kotlin #CompoundButton #CheckBox #RadioButton #Switch #ToggleButton

@avisper
Copy link
Author

avisper commented Dec 11, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment