2010-04-09 3 views
73

Если я использовал ImageButton с селектором для своего фона, есть ли состояние, которое я могу изменить, что изменит его внешний вид? Прямо сейчас я могу заставить его менять изображения при нажатии, но, похоже, нет «выделенного» или «выбранного» или подобного состояния, которое позволяет мне переключать его внешний вид по своему усмотрению.Android ImageButton с выбранным состоянием?

Вот мой XML; он меняет внешний вид при нажатии.

<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" /> 

+1

Использование ImageButton и отслеживание выбранного состояния кажется немного взломанным. Вы должны использовать кнопку переключения, если вы хотите переключить функциональность. –

ответ

180

Это работает для меня:

<?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> 

А потом в 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 
     } 

    } 

}); 

Для плавного перехода можно также указать время, анимации:

<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime"> 
+3

Это сработало для меня, но я хотел бы добавить, что нужно создать этот xml в вашей папке с возможностью рисования, и если вы хотите, чтобы ImageButton выделял при нажатии, вы должны использовать android: state_pressed, а не state_selected. Кроме того, это состояние должно быть выше элемента без состояния, так как оно менее общее. – wzbozon

+2

'ПРИМЕЧАНИЕ: порядок важен (первое совпадающее состояние (ы) - это то, что визуализируется' это действительно сработало, но странно, что я не получил ПОЧЕМУ? –

+2

В отсутствие каких-либо атрибутов состояния элемент будет соответствовать любому состоянию. второго элемента в селекторе в качестве состояния «поймать все». – joshrl

2

Попробуйте это:

<item 
    android:state_focused="true" 
    android:state_enabled="true" 
    android:drawable="@drawable/map_toolbar_details_selected" /> 

Кроме того, для цветов я имел успех с

<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> 
+0

Хм. Кажется, не помогает. Я использую CompoundButton. Есть ли состояние, специфичное для этого типа кнопки для on \ off? – Joren

+0

Да, это называется checked, см. _isChecked() _ http://developer.android.com/reference/android/widget/CompoundButton.html – Bostwickenator

9

Лучший способ сделать это без большего количества изображений:

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; 
     } 
    }); 
} 
+1

вы можете использовать getResources(). getColor (R.color.lightblue) для цвета из вашего xml. –

+0

@ András необходимо сохранить b Уттон нажал еще немного. Вы знаете, почему? – lionelmessi

+0

Вы можете использовать сон, но я не рекомендую его ... –

15

ToggleImageButton который реализует интерфейс Checkable и поддерживает OnCheckedChangeListener и android:checked атрибут 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); 
    } 
} 

Рез/значения/attrs.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="ToggleImageButton"> 
     <attr name="android:checked" /> 
    </declare-styleable> 
</resources> 
+0

Это прекрасный ответ для меня. – Damir

+1

Как его использовать? Я выполнил инструкцию: http://developer.android.com/training/custom-views/create-view.html, но я не мог заставить ее работать. – atisman

+2

Спасибо! Обратите внимание, что селектор с 'state_checked' не работает с этим, но вы должны использовать' state_selected'. –

1

Создание XML-файл в папке res/drawable. Например, "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> 

Вы можете объединить эти файлы вам нравится, например, изменение "bg_state_1" на "bg_state_deselected" и "bg_state_2" на "bg_state_selected".

В любой из этих файлов вы можете написать что-то вроде:

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
     android:shape="rectangle"> 
    <solid android:color="#ccdd00"/> 
    <corners android:radius="5dp"/> 
</shape> 

Создание в файле макета в ImageView или ImageButton со следующими атрибутами:

<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"/> 

Позже в коде:

image.setSelected(!image.isSelected()); 
Смежные вопросы