Android ImageButton với trạng thái đã chọn?


87

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

Đây là XML của tôi; nó chỉ thay đổi hình thức khi được 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 khó. Bạn nên sử dụng nút bật tắt, nếu bạn muốn chuyển đổi chức năng.
Andras Balázs Lajtha

Câu trả lời:


214

Điều này phù hợp với 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
        }

    }

});

Để chuyển đổi mượt mà, bạn cũng có thể đề cập đến thời gian hoạt ảnh:

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

3
Điều này phù hợp với tôi, nhưng tôi muốn nói thêm rằng người ta nên tạo xml này trong thư mục có thể vẽ của bạn và nếu bạn muốn ImageButton nổi bật khi nó được nhấn, bạn nên sử dụng android: state_pressed thay vì 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.
Denis Kutlubaev

3
NOTE: order is important (the first matching state(s) is what is renderedđiều này đã làm việc nhưng kỳ lạ là tôi không hiểu TẠI SAO?
Muhammad Babar

2
Trong trường hợp không có bất kỳ thuộc tính trạng thái nào, vật phẩm sẽ khớp với bất kỳ trạng thái nào. Vì vậy, hãy nghĩ đến mục thứ hai trong bộ chọn là trạng thái "bắt tất cả".
joshrl

2
Thứ tự không quan trọng, bạn chỉ cần đảm bảo rằng bạn cung cấp android:state_selected="false" đơn hàng mặc định!
Muhammad Babar

Làm cách nào tôi có thể làm điều tương tự trong một widget? Tôi có một nút nhưng dường như tôi không thể tìm ra cách thực hiện.
Si8

19

ToggleImageButtontriển khai Checkablegiao diện và hỗ trợ OnCheckedChangeListenerandroid:checkedthuộ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>

2
Tôi có thể sử dụng nó như thế nào? Tôi đã làm theo hướng dẫn trong: 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 với state_checkedkhông hoạt động với điều này, bạn phải sử dụng state_selected.
Florian von Stosch

11

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.
Beto Caldas

@ András cần phải nhấn nút thêm một chút. Bạn có biết tại sao lại như vậy không?
lionelmessi

3

Tạo một tệp XML trong một res/drawablethư mục. 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>

Ví dụ: bạn có thể kết hợp những tệp mình thích, thay đổi "bg_state_1" thành "bg_state_deselected" và "bg_state_2" thành "bg_state_selected".

Trong bất kỳ tệp nào trong số đó, bạn có thể viết những thứ 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 tệp bố cục 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());

2

Thử đi:

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

Ngoài ra đối với màu sắc tôi đã thành công

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

Hừ! Dường như không giúp được gì. Tôi đang sử dụng CompoundButton. Có trạng thái cụ thể cho loại nút đó để bật \ tắt không?
Joren

Có nó được gọi là checked xem isChecked () developer.android.com/reference/android/widget/...
Bostwickenator

0
if (iv_new_pwd.isSelected()) {
                iv_new_pwd.setSelected(false);
                Log.d("mytag", "in case 1");
                edt_new_pwd.setInputType(InputType.TYPE_CLASS_TEXT);
            } else {
                Log.d("mytag", "in case 1");
                iv_new_pwd.setSelected(true);
                edt_new_pwd.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
            }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.