Android ImageButton ที่มีสถานะที่เลือก?


87

หากฉันใช้ 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 และการติดตามสถานะที่เลือกดูเหมือนจะเป็นการแฮ็กเล็กน้อย คุณควรใช้ปุ่มสลับหากคุณต้องการสลับการทำงาน
Andras Balázs Lajtha

คำตอบ:


215

สิ่งนี้ใช้ได้กับฉัน:

<?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 นอกจากนี้สถานะนี้ควรอยู่เหนือรายการที่ไม่มีสถานะเนื่องจากเป็นสถานะทั่วไปน้อยกว่า
Denis Kutlubaev

3
NOTE: order is important (the first matching state(s) is what is renderedมันได้ผล แต่แปลกที่ฉันไม่เข้าใจว่าทำไม?
มูฮัมหมัดบาบาร์

2
ในกรณีที่ไม่มีแอตทริบิวต์สถานะรายการจะตรงกับสถานะใด ๆ ดังนั้นให้คิดว่ารายการที่สองในตัวเลือกเป็นสถานะ "จับทั้งหมด"
joshrl

2
คำสั่งซื้อไม่สำคัญคุณต้องแน่ใจว่าคุณได้ระบุandroid:state_selected="false" คำสั่งเริ่มต้นเท่านั้น!
มูฮัมหมัดบาบาร์

ฉันจะทำสิ่งเดียวกันในวิดเจ็ตได้อย่างไร? ฉันมีปุ่ม แต่ดูเหมือนจะคิดไม่ออกว่าจะทำอย่างไร
Si8

19

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

res / values ​​/ attrs.xml:

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

2
ฉันจะใช้มันได้อย่างไร? ฉันทำตามคำแนะนำใน: developer.android.com/training/custom-views/create-view.htmlแต่ไม่สามารถใช้งานได้
atisman

2
ขอบคุณ! โปรดทราบว่าตัวเลือกที่มีstate_checkedstate_selectedไม่ได้ทำงานกับแม้เรื่องนี้คุณจะต้องใช้
Florian von Stosch

11

วิธีที่ดีที่สุดในการดำเนินการนี้โดยไม่มีรูปภาพเพิ่มเติม:

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 ของคุณ
Beto Caldas

@ Andrásต้องกดปุ่มค้างไว้อีกเล็กน้อย คุณรู้ไหมว่าทำไมถึงเป็นเช่นนั้น?
lionelmessi

3

สร้างไฟล์ 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());

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>

อืม. ดูเหมือนจะไม่ช่วยอะไร ฉันใช้ CompoundButton มีสถานะเฉพาะสำหรับปุ่มประเภทนั้นสำหรับเปิด \ ปิดหรือไม่?
Joren

ใช่เรียกว่าตรวจสอบแล้วดู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);
            }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.