2010-04-09 17 views
73

Jeśli korzystałem z ImageButton z selektorem dla jego tła, czy istnieje stan, który mogę zmienić, który zmieni jego wygląd? W tej chwili mogę go zmienić po naciśnięciu, ale wydaje się, że nie ma "podświetlonego" lub "wybranego" lub podobnego stanu, który pozwala mi przełączać jego wygląd do woli.Android ImageButton z wybranym stanem?

Oto mój XML; zmienia się tylko wygląd po naciśnięciu.

<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

Korzystanie z przycisku ImageButton i śledzenie wybranego stanu wydaje się być nieco hackerem. Powinieneś użyć przełącznika, jeśli chcesz przełączyć funkcjonalność. –

Odpowiedz

180

Działa to dla mnie:

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

A potem w 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 
     } 

    } 

}); 

uzyskać płynne przejście można również wspomnieć czas animacji:

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

To działało dla mnie, ale chciałbym dodać, że należy utworzyć ten xml w folderze do rysowania i jeśli chcesz, aby ImageButton podświetlał się po naciśnięciu, powinieneś użyć android: state_pressed zamiast state_selected. Również ten stan powinien być powyżej elementu bez stanu, ponieważ jest mniej ogólny. – wzbozon

+2

'UWAGA: kolejność jest ważna (pierwszy pasujący stan (y) to to, co jest renderowane" to zadziałało, ale dziwne, że nie otrzymałem DLACZEGO? –

+2

W przypadku braku jakichkolwiek atrybutów stanu, element będzie pasował do dowolnego stanu. drugiego elementu w selektorze jako stanu "catch all" – joshrl

2

Spróbuj tego:

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

także dla kolorów i mieli sukces z

<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

Hmm. Wydaje się, że nie pomaga. Używam CompoundButton. Czy istnieje stan właściwy dla tego typu przycisku dla \ na wyłączenie? – Joren

+0

Tak, nazywa się to zaznaczone, patrz _isChecked() _ http://developer.android.com/reference/android/widget/CompoundButton.html – Bostwickenator

9

Najlepszym sposobem, aby to zrobić bez więcej zdjęć:

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

możesz użyć getResources(). getColor (R.color.lightblue) do koloru z twojego xml. –

+0

@ András musi zachować b utton przycisnął jeszcze trochę. Czy wiesz, dlaczego tak jest? – lionelmessi

+0

Możesz spać, ale nie polecam ... –

15

ToggleImageButton który implementuje interfejs Checkable i obsługuje atrybuty OnCheckedChangeListener i 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/wartości/attrs.xml:

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

To dla mnie idealna odpowiedź. – Damir

+1

Jak mogę z niego korzystać? Postępowałem zgodnie z instrukcją w: http://developer.android.com/training/custom-views/create-view.html, ale nie mogłem jej uruchomić. – atisman

+2

Dzięki! Zauważ, że selektor z 'state_checked' nie pracuje z tym jednak, musisz użyć' state_selected'. –

1

Utwórz plik XML w folderze res/drawable. Na przykład, "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> 

Można połączyć te pliki chcesz, na przykład, zmiana "bg_state_1" na "bg_state_deselected" i "bg_state_2" na "bg_state_selected".

W każdym z tych plików można napisać coś takiego:

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

Tworzenie w pliku layoutu się ImageView lub ImageButton z następujących cech:

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

Później w kodzie:

image.setSelected(!image.isSelected()); 
Powiązane problemy