Android ImageButton dengan status yang dipilih?

87

Jika saya menggunakan ImageButton dengan selektor untuk latar belakangnya, apakah ada keadaan yang dapat saya ubah yang akan membuatnya mengubah tampilannya? Saat ini saya bisa mendapatkannya untuk mengubah gambar saat ditekan, tetapi tampaknya tidak ada status "disorot" atau "dipilih" atau serupa yang memungkinkan saya mengubah tampilannya sesuka hati.

Ini XML saya; itu hanya mengubah tampilan saat ditekan.

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

Joren
sumber
1
Menggunakan ImageButton, dan melacak status yang dipilih tampaknya sedikit diretas. Anda harus menggunakan tombol sakelar, jika Anda ingin beralih fungsionalitas.
Andras Balázs Lajtha

Jawaban:

215

Ini bekerja untuk saya:

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

Dan kemudian di 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
        }

    }

});

Untuk transisi yang mulus, Anda juga dapat menyebutkan waktu animasi:

<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
joshrl
sumber
3
Ini berfungsi untuk saya, tetapi saya ingin menambahkan, yang itu harus membuat xml ini di folder drawable Anda dan jika Anda ingin ImageButton disorot saat ditekan, Anda harus menggunakan android: state_pressed daripada state_selected. Juga, status ini harus di atas item tanpa status, karena ini kurang umum.
Denis Kutlubaev
3
NOTE: order is important (the first matching state(s) is what is renderedini berhasil tetapi aneh saya tidak mengerti MENGAPA?
Muhammad Babar
2
Jika tidak ada atribut negara bagian, item tersebut akan cocok dengan semua negara bagian. Jadi pikirkan item kedua di pemilih sebagai status "tangkap semua".
joshrl
2
Urutan tidak penting, Anda hanya perlu memastikan bahwa Anda menyediakan android:state_selected="false" yang default!
Muhammad Babar
Bagaimana saya bisa melakukan hal yang sama di widget? Saya memiliki tombol tetapi saya tidak tahu bagaimana melakukannya.
Si8
19

ToggleImageButtonyang mengimplementasikan Checkableantarmuka dan dukungan OnCheckedChangeListenerserta android:checkedatribut 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>
vokilam.dll
sumber
2
Bagaimana saya bisa menggunakannya? Saya mengikuti instruksi di: developer.android.com/training/custom-views/create-view.html tetapi saya tidak dapat membuatnya berfungsi.
atisman
2
Terima kasih! Perhatikan bahwa pemilih dengan state_checkedtidak berfungsi dengan ini, Anda harus menggunakan state_selected.
Florian von Stosch
11

Cara terbaik untuk melakukan ini tanpa lebih banyak gambar:

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;
        }
    });
}
András
sumber
1
Anda bisa menggunakan getResources (). getColor (R.color.lightblue) untuk mewarnai dari xml Anda.
Beto Caldas
@ András perlu terus menekan tombolnya sedikit lagi. Tahukah Anda mengapa demikian?
lionelmessi
3

Buat file XML dalam res/drawablefolder. Misalnya, "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>

Anda dapat menggabungkan file-file yang Anda suka, misalnya, ubah "bg_state_1" menjadi "bg_state_deselected" dan "bg_state_2" menjadi "bg_state_selected".

Di salah satu file tersebut, Anda dapat menulis sesuatu seperti:

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

Buat dalam file layout sebuah ImageView atau ImageButton dengan atribut berikut:

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

Nanti di kode:

image.setSelected(!image.isSelected());
CoolMind
sumber
2

Coba ini:

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

Juga untuk warna yang berhasil saya gunakan

<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>
Alex Volovoy
sumber
Hmm. Sepertinya tidak membantu. Saya menggunakan CompoundButton. Apakah ada keadaan khusus untuk jenis tombol itu untuk on \ off?
Joren
Ya itu disebut diperiksa lihat 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);
            }
MEGHA DOBARIYA
sumber