2010-04-09 43 views
73

Nếu tôi đang sử dụng ImageButton với bộ chọn cho nền của nó, có trạng thái nào tôi có thể thay đổi để làm cho nó thay đổi diện mạo của nó không? Ngay bây giờ tôi có thể làm cho nó thay đổi hình ảnh khi nhấn, nhưng có vẻ như không có "đánh dấu" hoặc "được chọn" hoặc trạng thái tương tự cho phép tôi chuyển đổi hình dạng của nó theo ý thích.Android ImageButton với trạng thái đã chọn?

Đây là XML của tôi; nó chỉ thay đổi hình dạng khi nhấn.

<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

Sử dụng ImageButton và theo dõi trạng thái đã chọn có vẻ hơi bị hack. Bạn nên sử dụng nút chuyển đổi, nếu bạn muốn chuyển đổi chức năng. –

Trả lời

180

này làm việc cho tôi:

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

Và sau đó trong 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 
     } 

    } 

}); 

Đối với chuyển đổi suôn sẻ bạn cũng có thể đề cập đến thời gian hoạt hình:

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

Điều này làm việc cho tôi, nhưng tôi muốn thêm, rằng một trong những nên tạo xml này trong thư mục drawable của bạn và nếu bạn muốn ImageButton để làm nổi bật khi nó ép, bạn nên sử dụng android: state_pressed chứ không phải là state_selected. Ngoài ra, trạng thái này phải ở trên một mục không có trạng thái vì nó ít chung chung hơn. – wzbozon

+2

'LƯU Ý: thứ tự quan trọng (trạng thái khớp đầu tiên là gì được hiển thị' này đã làm việc nhưng lạ tôi không nhận được WHY? –

+2

Trong trường hợp không có bất kỳ thuộc tính trạng thái nào, mục sẽ khớp với bất kỳ trạng thái nào. của mục thứ hai trong bộ chọn là trạng thái "bắt tất cả" – joshrl

2

Hãy thử điều này:

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

Cũng cho màu sắc tôi đã thành công với

<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. Dường như không giúp được gì. Tôi đang sử dụng một CompoundButton. Có trạng thái cụ thể cho loại nút đó để bật \ off không? – Joren

+0

Có nó được gọi là kiểm tra xem _isChecked() _ http://developer.android.com/reference/android/widget/CompoundButton.html – Bostwickenator

9

Cách tốt nhất để làm điều này mà không có thêm hình ảnh:

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

bạn có thể sử dụng getResources(). getColor (R.color.lightblue) để tô màu từ xml của bạn –

+0

@ András cần giữ lại b utton ép thêm một chút. Bạn có biết tại sao không? – lionelmessi

+0

Bạn có thể sử dụng giấc ngủ, nhưng tôi không khuyên bạn nên ... –

15

ToggleImageButton mà triển khai giao diện Checkable và hỗ trợ OnCheckedChangeListenerandroid:checked thuộc tính 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/values ​​/ attrs.xml:

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

Đây là câu trả lời hoàn hảo cho tôi. – Damir

+1

Tôi có thể sử dụng nó như thế nào? Tôi đã làm theo hướng dẫn trong: http://developer.android.com/training/custom-views/create-view.html nhưng tôi không thể làm cho nó hoạt động. – atisman

+2

Cảm ơn! Lưu ý rằng một bộ chọn có 'state_checked'does không hoạt động với điều này, bạn phải sử dụng' state_selected'. –

1

Tạo một file XML trong một thư mục res/drawable. Ví dụ, "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> 

Bạn có thể kết hợp các tập tin mà bạn thích, ví dụ, thay đổi "bg_state_1" thành "bg_state_deselected" và "bg_state_2" thành "bg_state_selected".

Trong bất kỳ các tập tin bạn có thể viết một cái gì đó như:

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

Tạo trong một file bố trí một ImageView hoặc ImageButton với các thuộc tính sau:

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

Sau đó trong mã:

image.setSelected(!image.isSelected()); 
Các vấn đề liên quan