Il y a déjà 20 réponses, mais oserais-je dire que je pense avoir la meilleure.
Cela utilise la liaison des données de vue, donc la première chose que vous voudrez faire est d'ajouter ceci dans le module build.gradle
de votre module.
android {
dataBinding {
enabled = true
}
}
Ensuite, vous pouvez créer une disposition avec la hiérarchie de vues souhaitée, par exemple:
fancy_radio_button.xml
Cela peut avoir l'apparence que vous souhaitez, assurez-vous simplement de définir android:clickable="false"
sur le RadioButton
, et d'utiliser les variables de liaison de données lorsque cela est nécessaire.
Cette disposition est gérée par cette classe:
FancyRadioGroup.java
package com.example.app;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RadioGroup;
import com.example.app.FancyRadioButtonBinding;
import java.util.ArrayList;
public class FancyRadioGroup extends RadioGroup implements View.OnClickListener {
private final ArrayList radioButtons = new ArrayList<>();
private OnSelectionChangedListener selectionChangedListener;
public FancyRadioGroup(Context context) {
super(context);
}
public FancyRadioGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnSelectionChangedListener(OnSelectionChangedListener selectionChangedListener) {
this.selectionChangedListener = selectionChangedListener;
}
public int addOption(String title, String description) {
// inflate view and get binding
FancyRadioButtonBinding buttonBinding = FancyRadioButtonBinding.inflate(LayoutInflater.from(getContext()), this, true);
// set title and description
buttonBinding.setTitle(title);
buttonBinding.setDescription(description);
// give the button an id (just use the index)
buttonBinding.setButtonId(radioButtons.size());
// set the root view's tag to the binding, so we can get the binding from the view
View root = buttonBinding.getRoot();
root.setTag(buttonBinding);
// set click listener on the whole view, so we can click anywhere
root.setOnClickListener(this);
radioButtons.add(buttonBinding);
// return button id to caller, so they know what was clicked
return buttonBinding.getButtonId();
}
@Override
public void onClick(View v) {
for (FancyRadioButtonBinding binding : radioButtons) {
binding.setChecked(v.getTag() == binding);
}
if (selectionChangedListener != null) {
selectionChangedListener.onSelectionChanged(getSelected());
}
}
public int getSelected() {
for (FancyRadioButtonBinding binding : radioButtons) {
if (binding.getChecked()) {
return binding.getButtonId();
}
}
return -1;
}
public interface OnSelectionChangedListener {
void onSelectionChanged(int buttonId);
}
}
Pour utiliser, ajoutez simplement le FancyRadioGroup
à votre vue:
activity_foo.xml
Ensuite, ajoutez vos options:
FooActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FancyRadioGroup radioGroup = findViewById(R.id.radio_group);
radioGroup.addOption("The First One", "This option is recommended for users who like the number one.");
radioGroup.addOption("The Second One", "For advanced users. Larger than one.");
radioGroup.setOnSelectionChangedListener(this::doSomething);
}
private void doSomething(int id) {
Toast.makeText(this, "selected: "+id, Toast.LENGTH_SHORT).show();
}