Отключить переключатель с Android
Приложение представляет собой пошаговый секвенсор с 16 радиогруппами по 8 кнопок в каждой группе. Он работает отлично, за исключением того, что когда в группе выбрана кнопка, я не могу ее отключить, если не использую созданную мной кнопку очистки, чтобы очистить все радиогруппы. Что я хотел бы добавить, так это некоторый код, который говорит, что когда выбранный переключатель снова выбран, он просто выключается, как тумблер. Я попытался использовать переключатели, но затем возникли другие проблемы с этим методом. Ниже приведены две попытки, но обе просто останавливает меня, используя кнопку
final RadioGroup radioGroup1 = (RadioGroup)findViewById(R.id.RadioGroup1);
RadioButton D1 = (RadioButton)findViewById(R.id.RadioButtonD1);
Button D1 = (Button)findViewById(R.id.RadioButtonD1);
D1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PdBase.sendFloat("D1", 74);
int selectedTypeId = radioGroup1.getCheckedRadioButtonId();
RadioButton D1 = (RadioButton) findViewById(selectedTypeId);
if(D1 != null) // This will be null if none of the radio buttons are selected
radioGroup1.clearCheck();
PdBase.sendFloat("D1", 0);
}
});
RadioButton lC1 = (RadioButton)findViewById(R.id.RadioButtonlowC1);
lC1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int selectedTypeId = radioGroup1.getCheckedRadioButtonId();
RadioButton lC1 = (RadioButton) findViewById(R.id.RadioButtonlowC1);
if (selectedTypeId == -1){
PdBase.sendFloat("lC1", 72);
}
else if (selectedTypeId == R.id.RadioButtonlowC1) {
radioGroup1.clearCheck();
PdBase.sendFloat("lC1", 0);
}
}
});
7 ответов
Недавно у меня возникла такая же потребность - создать радиогруппу, в которой выбранный элемент можно отменить, нажав его снова. Я обнаружил, что не могу добиться этого с помощью слушателей, но я смог сделать это с помощью пользовательского RadioButton
, вот так...
public class ToggleableRadioButton extends RadioButton {
// Implement necessary constructors
@Override
public void toggle() {
if(isChecked()) {
if(getParent() instanceof RadioGroup) {
((RadioGroup)getParent()).clearCheck();
}
} else {
setChecked(true);
}
}
}
Обратите внимание, что кнопка переключается по-разному в зависимости от ее текущего состояния - т.е. setChecked(true)
на баттоне против колла clearCheck()
на группу. Если setChecked()
используется в обоих случаях, кнопка, которая была только что отменена, не может быть немедленно повторно выбрана - логика в RadioGroup
кажется, немедленно отменить это.
Чтобы использовать эту кнопку, просто замените <RadioButton>
теги с <your.package.ToggleableRadioButton>
в вашем макете XML.
Я просто использовал ответ от spaaarky21
и мой полный код выглядит так, и он работает нормально!
Java класс
public class ToggleableRadioButton extends RadioButton {
public ToggleableRadioButton(Context context) {
super(context);
}
public ToggleableRadioButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ToggleableRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ToggleableRadioButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void toggle() {
if(isChecked()) {
if(getParent() instanceof RadioGroup) {
((RadioGroup)getParent()).clearCheck();
}
} else {
setChecked(true);
}
}
}
И для макета XML
<com.smart_dent.adapters.ToggleableRadioButton android:id="@+id/tejido_blando_perfil_convexo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tejido_blando_convexo_label" />
В этом случае вам просто нужно изменить пакет, это легко найти, он находится на вершине Java Class Flie (если вы создали его из Android Studio)
Это на самом деле может быть сделано со слушателями, но с OnTouchListener
, который сработает до изменения состояния кнопки вместо обычного OnClickListener
, Следующие работы для меня:
View.OnTouchListener radioButtonOnTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (((RadioButton) v).isChecked()) {
// If the button was already checked, uncheck them all
radioGroup.clearCheck();
// Prevent the system from re-checking it
return true;
}
return false;
}
};
radioButton1.setOnTouchListener(radioButtonOnTouchListener);
radioButton2.setOnTouchListener(radioButtonOnTouchListener);
куда radioGroup
является родителем radioButton1
а также radioButton2
Редактировать от @spaaarky21 ответ
@Override
public void toggle() {
if (isChecked()) {
if (getParent() instanceof RadioGroup) {
((RadioGroup) getParent()).clearCheck();
}
// add else here when a single radioButton without radioGroup
else {
setChecked(false);
}
} else {
setChecked(true);
}
}
Это также делает работу:
public final class ToggleAbleRadioButton extends AppCompatRadioButton {
public ToggleAbleRadioButton(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override public void toggle() {
setChecked(!isChecked());
}
}
Вы можете использовать логическое значение для включения и выключения кнопки.
Добавьте в код логическое значение:
var radioButton1IsSelected = false
Затем настройте onClickListener для кнопки:
radioButton1.setOnClickListener {
radioButton1IsSelected = !radioButton1IsSelected
radioButton1.isChecked = radioButton1IsSelected
}
Вот котлин-версия кастомаToggleableRadioButton
снять флажок без необходимости использованияRadioGroup
.
class ToggleableRadioButton constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
AppCompatRadioButton(context, attrs, defStyleAttr) {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
override fun toggle() {
isChecked = !isChecked
}
}
С настройками по умолчанию, т.е.super.toggle()
не снимает флажок, поскольку он явно контролируетсяRadioButton.java
Как указано в документации, если переключатель уже установлен, переключатель не будет вызван.