Отключить переключатель с 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

Как указано в документации, если переключатель уже установлен, переключатель не будет вызван.

Другие вопросы по тегам