I have a chip group and inside that I am adding Choice Chips programmatically and I have a button called Select All for selecting all if some of them selected and Same Button for Deselecting All chips in a single click.
Now Please guide me some proper way or It would be great if it can be done using chip group instead of ArrayList of chip
Thanks in advance :)
For deselecting you can use clearCheck and for selection you've to go through for loop
I have created a general Extension function for the above solution in kotlin
I think that this is the proper solution
fun ChipGroup.applyCheckedOnAll(isChecked: Boolean){
if (isChecked){
for (index in 0 until this.childCount) {
val chip:Chip = this.getChildAt(index) as Chip
chip.isChecked = true
}
}else {
this.clearCheck()
}
}
ChipGroup chipGroup = view.findViewById(R.id.chipGroup );
for (int i = 0; i < chipGroup.getChildCount(); i++) {
Chip chip = (Chip) chipGroup.getChildAt(i);
chip.setChecked(false);
}
Clears the selection. When the selection is cleared, no chip in this group is selected
chipgroup.clearCheck()
Related
TL;DR - What is the correct way to programatically select a default choice Chip that is a child of a ChipGroup in Android?
--
In my android app, I am using com.google.android.material.chip.Chip styled as #style/Widget.MaterialComponents.Chip.Choice components to represent choices of activities a user can select for a given route (think walk, bike, etc)
Because a route can have different types of activities, I insert each type as a different chip programatically into a com.google.android.material.chip.ChipGroup. I also select the default chip as being the first one inserted in the list using the following code during onViewCreated() of my fragment
private fun setupTypeSelection(types: List<Type>) {
types.forEach { type ->
val chip = layoutInflater.inflate(R.layout.chip_type, viewBinding.typeChipGroup, false) as Chip
chip.tag = type
/* Init chip text and icon */
chip.setOnClickListener {
/* Update selected type */
}
if (currentType == null) {
chip.isSelected = true
currentType = type
}
viewBinding.typeChipGroup.addView(chip)
}
}
Here's the layout definition of the ChipGroup, where a I set single selection, etc
chip_group_layout.xml
<com.google.android.material.chip.ChipGroup
android:id="#+id/type_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_medium"
app:chipSpacingHorizontal="#dimen/margin_medium"
app:selectionRequired="true"
app:singleLine="true"
app:singleSelection="true" />
And here is the chip layout
chip_type.xml
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="#style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipIconEnabled="true" />
The problem I'm facing is that the chip that was set programatically as selected chip.isSelected = true stays selected even after the user selects a different one through UI interaction.
What is the correct way to programatically select a default choice Chip that is a child of a ChipGroup in Android?
Found my answer.
Use View.generateViewId() and assign the new Id to the
newly create chip. Then, add
Add chip to its parent ChipGroup
Check chip view ChipGroup using viewBinding.typeChipGroup.check(id)
This is the final code:
private fun setupTypeSelection(types: List<Trail.Type>) {
types.forEach { type ->
val chip = layoutInflater.inflate(R.layout.chip_trail_type, viewBinding.typeContainer, false) as Chip
chip.id = View.generateViewId()
/* Set chip details as usual */
viewBinding.typeContainer.addView(chip)
if (currentType == null) viewBinding.typeChipGroup.check(chip.id)
}
}
currentType == null condition will be false for next selection. Are you making it null anywhere else?
Use ChipGroup's setOnCheckedChangeListener to check the state of chip selection instead of chip.setOnClickListener
val chipGroup = findViewById<ChipGroup>(R.id.chip_group)
val tileSize320 = findViewById<Chip>(R.id.tile_size320)
chipGroup.check(tileSize320)
I want to do actions with 9 buttons.Is there anyway to do action with 9 buttons in one time,not one by one.
If I could add variable to findViewById() I would solve problem.
For example I want to select 9 button at once(with for loop) like below
for(i in 1..9){
findViewById(R.id.button+i).text="New Text"
}
This way not working,please suggest optimal ways.
I want like this in javascript equivalent:
document.getElementById("button"+i)
Declare this in your activity:
var buttons: ArrayList<Button> = arrayListOf()
and in onCreate():
for (i in 1..100) {
buttons.add(findViewById<Button>(resources.getIdentifier("button" + i, "id", this.getPackageName())))
}
Now you have all your buttons in a list.
if you want to change the state of your buttons, say disable them all:
buttons.forEach { it.isEnabled = false }
You can set tag for each button (like button1, button2, etc.) and do something like this
for(i in 1..9){
(view.findViewWithTag("button"+i.toString()) as Button).text = "New Text"
}
I add radiobuttons in code:
options.map {
val radioOption = RadioButton(infoLabel.context)
radioOption.text = it
radioOption.isClickable = isReadOnly
if (value.contains(it))
radioOption.isChecked = true
infoRadioGroup.addView(radioOption)
}
In options I have two elements. On start on of them is selected.When I start the app and try to select the second one I get two selected radiobuttons. The first one is still checked. Any ideas?
This can only happen when the Id of both RadioButton are same. Make sure the ID of every RadioButton is unique.
I resolve my problem:
radioOption.setOnCheckedChangeListener { buttonView, isChecked ->
val count = infoRadioGroup.childCount
if (isChecked)
for (i in 0 until count) {
val radio = infoRadioGroup.getChildAt(i)
if (radio is RadioButton) {
radio.isChecked = radio.text == buttonView.text
}
}
}
I got the position of a radio in a radio group by using indexOfChild. How can I use this index to check the radio that has this particular index?
Try this
radioGroup.check(((RadioButton)radioGroup.getChildAt(index)).getId())
for (i in listCategory.indices){
if ((categoryRadioGroup[i] as RadioButton).isChecked) {
Toast.makeText(myContext, "$i", Toast.LENGTH_SHORT).show()
}
}
I have a radio group which I do not want to user to be able to select any of the buttons until a particular checkbox is selected within my app. If the checkbox is unticked then this disables the radio-group. How do I go about doing this.
The real trick is to loop through all children view (in this case: CheckBox) and call it's setEnabled(boolean)
Something like this should do the trick:
//initialize the controls
final RadioGroup rg1 = (RadioGroup)findViewById(R.id.radioGroup1);
CheckBox ck1 = (CheckBox)findViewById(R.id.checkBox1);
//set setOnCheckedChangeListener()
ck1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton checkBox, boolean checked) {
//basically, since we will set enabled state to whatever state the checkbox is
//therefore, we will only have to setEnabled(checked)
for(int i = 0; i < rg1.getChildCount(); i++){
((RadioButton)rg1.getChildAt(i)).setEnabled(checked);
}
}
});
//set default to false
for(int i = 0; i < rg1.getChildCount(); i++){
((RadioButton)rg1.getChildAt(i)).setEnabled(false);
}
If you have just a few radio buttons, better way would be to setClickable(false) for all children
radiobutton1.setClickable(false);
radiobutton2.setClickable(false);
radiobutton3.setClickable(false);
RadioGroup cannot be disabled directly, we have to loop through the radio button and setEnabled as false.
// To disable the Radio Buttons of radio group.
for (int i = 0; i < radioGroup.getChildCount(); i++) {
radioUser.getChildAt(i).setEnabled(false);
}
If you want to implement the same for Kotlin, Here's my code->
where rgNotificationType is the radio group name.
for (i in 0 until rgNotificationType.childCount) {
(rgNotificationType.getChildAt(i)).isEnabled = false
}
You can use the onCheckedChangeListener on your CheckBox and use the method setEnabled on your RadioGroup.
Best wishes,
Tim
By using kolin's extensions:
fun RadioGroup.setChildrenEnable(enable: Boolean) {
for (i in 0 until this.childCount) {
this.getChildAt(i).isEnabled = enable
}
}
And in your code you can just call the function like this:
radioGroup.setChildrenEnable(false)
Kotlin Solution
for (index in 0..radio.childCount - 1)
radio.getChildAt(index).isEnabled = false
Take actions according to the state of the checkbox and set the radiogroup accordingly.
Assuming that you have a radio-group named radiogroup you can enable or disable the radiogroup by
radiogroup.setEnabled(true);
Add a OnCheckedChangeListener() to your checkbox.