Android: especifique duas imagens diferentes para o botão de alternância usando XML

100

Estou tentando substituir a ToggleButtonaparência padrão . Aqui está o XML que define ToggleButton:

<ToggleButton android:id="@+id/FollowAndCenterButton"
        android:layout_width="30px"
        android:layout_height="30px"
        android:textOn="" android:textOff="" android:layout_alignParentLeft="true"
        android:layout_marginLeft="5px"
        android:layout_marginTop="5px" android:background="@drawable/locate_me"/>

Agora, temos dois ícones 30 x 30 que queremos usar para os estados clicado / não clicado. No momento, temos um código que altera programaticamente o ícone de plano de fundo dependendo do estado:

centeredOnLocation.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            if (centeredOnLocation.isChecked()) {
                centeredOnLocation.setBackgroundDrawable(getResources().getDrawable(R.drawable.locate_me_on));
            } else {
                centeredOnLocation.setBackgroundDrawable(getResources().getDrawable(R.drawable.locate_me));
            }
        }
});

Obviamente, estou procurando uma maneira melhor de fazer isso. Tentei fazer um seletor para a imagem de fundo, que mudaria automaticamente entre os estados:

 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:drawable="@drawable/locate_me" /> <!-- default -->
 <item android:state_checked="true"
       android:drawable="@drawable/locate_me_on" /> <!-- pressed -->
 <item android:state_checked="false"
       android:drawable="@drawable/locate_me" /> <!-- unchecked -->

Mas isso não funciona; lendo a ToggleButtonAPI ( http://developer.android.com/reference/android/widget/ToggleButton.html ), parece que os únicos atributos xml herdados são

    XML Attributes
Attribute Name  Related Method  Description
android:disabledAlpha       The alpha to apply to the indicator when disabled. 
android:textOff         The text for the button when it is not checked. 
android:textOn      The text for the button when it is checked. 

Não parece haver o atributo android: state_checked, apesar da classe ter o método isChecked()e setChecked().

Então, há uma maneira de fazer o que eu quero em XML ou estou preso com minha solução alternativa complicada?

I82Much
fonte
Observe, se você não estiver usando texto, acho melhor usar CompoundButton.
Timmmm
1
Desconsidere isso; CompoundButtoné abstrato!
Timmmm

Respostas:

159

Seu código está bom. No entanto, o botão de alternância exibirá o primeiro item em seu seletor que corresponda, portanto, o padrão deve vir por último. Organize os itens da seguinte maneira para garantir que todos sejam utilizados:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:state_pressed="true" /> //currently pressed turning the toggle on
    <item android:state_pressed="true" /> //currently pressed turning the toggle off
    <item android:state_checked="true" /> //not pressed default checked state
    <item /> //default non-pressed non-checked
</selector>
m_vitaly
fonte
3
Isso faz todo o sentido; Nunca fiz a conexão entre as instruções selector e switch.
I82Much,
Você fez meu dia ... Tive problemas com o botão, caixa de seleção e tentei o botão de rádio também, finalmente este post foi útil. Muito obrigado Vitaly Polonetsky e I82Much
David Prun
8
a documentação em algum lugar diz que ele lê a partir do topo, parando no primeiro estado cujas condições são todas atendidas, então se o padrão estiver no topo, ele nunca passará daquele drawable.
Travis,
1
@ I82Muito a switchselecionaria sempre o "correto", independentemente da ordem, ele se comporta mais como um prolongado if-elseif-elseif-elsecom condições como state_x == true && state_y == false && state_z = true.
TWiStErRob