Android ImageButton mit einem ausgewählten Status?

87

Wenn ich einen ImageButton mit einem Selektor als Hintergrund verwendet habe, gibt es einen Status, den ich ändern kann, wodurch sich sein Erscheinungsbild ändert? Im Moment kann ich es dazu bringen, Bilder zu ändern, wenn es gedrückt wird, aber es scheint keinen "hervorgehobenen" oder "ausgewählten" oder ähnlichen Zustand zu geben, der es mir ermöglicht, sein Erscheinungsbild nach Belieben umzuschalten.

Hier ist mein XML; es ändert nur das Aussehen, wenn es gedrückt wird.

 <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
quelle
1
Die Verwendung eines ImageButton und das Verfolgen des ausgewählten Status scheint ein bisschen ein Hack zu sein. Sie sollten eine Umschalttaste verwenden, wenn Sie die Umschaltfunktion nutzen möchten.
Andras Balázs Lajtha

Antworten:

213

Das funktioniert bei mir:

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

Und dann in 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
        }

    }

});

Für einen reibungslosen Übergang können Sie auch die Animationszeit angeben:

<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
joshrl
quelle
3
Dies hat bei mir funktioniert, aber ich möchte hinzufügen, dass man diese XML in Ihrem Zeichenordner erstellen sollte und wenn Sie möchten, dass ImageButton beim Drücken hervorgehoben wird, sollten Sie android: state_pressed anstelle von state_selected verwenden. Außerdem sollte dieser Status über einem Element ohne Status liegen, da er weniger allgemein ist.
Denis Kutlubaev
3
NOTE: order is important (the first matching state(s) is what is renderedDas hat funktioniert, aber seltsam, ich habe nicht verstanden, warum?
Muhammad Babar
2
Wenn keine Statusattribute vorhanden sind, stimmt das Element mit jedem Status überein. Stellen Sie sich also das zweite Element in der Auswahl als den Status "Alle fangen" vor.
Joshrl
2
Die Reihenfolge ist nicht wichtig. Sie müssen nur sicherstellen, dass Sie android:state_selected="false" die Standardbestellung angeben!
Muhammad Babar
Wie kann ich dasselbe in einem Widget tun? Ich habe einen Knopf, aber ich kann nicht herausfinden, wie es geht.
Si8
19

ToggleImageButtonwelches die CheckableSchnittstelle implementiert OnCheckedChangeListenerund ein android:checkedXML-Attribut unterstützt:

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
quelle
2
Wie kann ich es benutzen? Ich habe die Anweisungen in: developer.android.com/training/custom-views/create-view.html befolgt , aber ich konnte es nicht zum Laufen bringen.
Atisman
2
Vielen Dank! Beachten Sie, dass ein Selektor mit state_checkednicht funktioniert, Sie müssen jedoch verwenden state_selected.
Florian von Stosch
11

Der beste Weg, dies ohne weitere Bilder zu tun:

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
quelle
1
Sie können getResources (). getColor (R.color.lightblue) verwenden, um aus Ihrer XML-Datei zu färben.
Beto Caldas
@ András muss den Knopf noch ein bisschen gedrückt halten. Weißt du warum das so ist?
Lionelmessi
3

Erstellen Sie eine XML-Datei in einem res/drawableOrdner. Zum Beispiel "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>

Sie können die gewünschten Dateien kombinieren, indem Sie beispielsweise "bg_state_1" in "bg_state_deselected" und "bg_state_2" in "bg_state_selected" ändern.

In jede dieser Dateien können Sie Folgendes schreiben:

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

Erstellen Sie in einer Layoutdatei eine ImageView oder einen ImageButton mit den folgenden Attributen:

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

Später im Code:

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

Versuche dies:

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

Auch für Farben hatte ich Erfolg mit

<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
quelle
Hmm. Scheint nicht zu helfen. Ich benutze einen CompoundButton. Gibt es einen spezifischen Status für diese Art von Schaltfläche für Ein / Aus?
Joren
Ja, es heißt überprüft, siehe 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
quelle