Android ImageButton com um estado selecionado?
-
25-09-2019 - |
Pergunta
Se eu estava usando um button com um seletor para seu plano de fundo, existe um estado que eu possa mudar que fará com que isso mude sua aparência? No momento, posso alterar as imagens quando pressionado, mas parece não haver um estado "destacado" ou "selecionado" ou similar que me permita alternar sua aparência à vontade.
Aqui está meu XML; Isso só muda a aparência quando pressionado.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/map_toolbar_details_selected" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/map_toolbar_details_selected" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/map_toolbar_details_selected" />
<item android:drawable="@drawable/map_toolbar_details" />
Solução
Isso funciona para mim:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- NOTE: order is important (the first matching state(s) is what is rendered) -->
<item
android:state_selected="true"
android:drawable="@drawable/info_icon_solid_with_shadow" />
<item
android:drawable="@drawable/info_icon_outline_with_shadow" />
</selector>
E então em Java:
//assign the image in code (or you can do this in your layout xml with the src attribute)
imageButton.setImageDrawable(getBaseContext().getResources().getDrawable(R.drawable....));
//set the click listener
imageButton.setOnClickListener(new OnClickListener() {
public void onClick(View button) {
//Set the button's appearance
button.setSelected(!button.isSelected());
if (button.isSelected()) {
//Handle selected state change
} else {
//Handle de-select state change
}
}
});
Para uma transição suave, você também pode mencionar o tempo de animação:
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
Outras dicas
ToggleImageButton
que implementa Checkable
interface e suportes OnCheckedChangeListener
e android:checked
Atributo XML:
public class ToggleImageButton extends ImageButton implements Checkable {
private OnCheckedChangeListener onCheckedChangeListener;
public ToggleImageButton(Context context) {
super(context);
}
public ToggleImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
setChecked(attrs);
}
public ToggleImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setChecked(attrs);
}
private void setChecked(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ToggleImageButton);
setChecked(a.getBoolean(R.styleable.ToggleImageButton_android_checked, false));
a.recycle();
}
@Override
public boolean isChecked() {
return isSelected();
}
@Override
public void setChecked(boolean checked) {
setSelected(checked);
if (onCheckedChangeListener != null) {
onCheckedChangeListener.onCheckedChanged(this, checked);
}
}
@Override
public void toggle() {
setChecked(!isChecked());
}
@Override
public boolean performClick() {
toggle();
return super.performClick();
}
public OnCheckedChangeListener getOnCheckedChangeListener() {
return onCheckedChangeListener;
}
public void setOnCheckedChangeListener(OnCheckedChangeListener onCheckedChangeListener) {
this.onCheckedChangeListener = onCheckedChangeListener;
}
public static interface OnCheckedChangeListener {
public void onCheckedChanged(ToggleImageButton buttonView, boolean isChecked);
}
}
res/valores/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ToggleImageButton">
<attr name="android:checked" />
</declare-styleable>
</resources>
A melhor maneira de fazer isso sem mais imagens:
public static void buttonEffect(View button){
button.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
v.getBackground().setColorFilter(0xe0f47521,PorterDuff.Mode.SRC_ATOP);
v.invalidate();
break;
}
case MotionEvent.ACTION_UP: {
v.getBackground().clearColorFilter();
v.invalidate();
break;
}
}
return false;
}
});
}
Experimente isso:
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="@drawable/map_toolbar_details_selected" />
Também para cores com o qual tive sucesso
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:color="@color/primary_color" />
<item
android:color="@color/secondary_color" />
</selector>
Criar um arquivo XML em um res/drawable
pasta. Por exemplo, "btn_image.xml":
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_state_1"
android:state_pressed="true"
android:state_selected="true"/>
<item android:drawable="@drawable/bg_state_2"
android:state_pressed="true"
android:state_selected="false"/>
<item android:drawable="@drawable/bg_state_selected"
android:state_selected="true"/>
<item android:drawable="@drawable/bg_state_deselected"/>
</selector>
Você pode combinar esses arquivos que você gosta, por exemplo, altere "bg_state_1" para "bg_state_deselected" e "bg_state_2" para "bg_state_selected".
Em qualquer um desses arquivos, você pode escrever algo como:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ccdd00"/>
<corners android:radius="5dp"/>
</shape>
Crie em um arquivo de layout Um ImageView ou ImageButton com os seguintes atributos:
<ImageView
android:id="@+id/image"
android:layout_width="50dp"
android:layout_height="50dp"
android:adjustViewBounds="true"
android:background="@drawable/btn_image"
android:padding="10dp"
android:scaleType="fitCenter"
android:src="@drawable/star"/>
Posteriormente no código:
image.setSelected(!image.isSelected());