2015-11-26 3 views
16

Android Studio 2.0 Vorschau nicht wechselnstate_checked nicht Imageview an und aus

Hallo,

Ich habe diesen Selektor, der mit einem imageview verbunden ist. Ich möchte die imageview ein- und ausschalten. Aus wird eine grüne Farbe und eine rote Farbe angezeigt. Wenn ich aber auf imageview klicke, passiert nichts. Ich habe verschiedene Kombinationen von state_pressed und state_checked ausprobiert. Und jetzt wird es zu verwirrend. Was vermisse ich hier.

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_checked="false" 
      android:drawable="@drawable/bottom_left_border"/> 

    <item android:state_checked="true" 
      android:drawable="@drawable/bottom_left_border_pressed"> 
    </item> 
</selector> 

Vielen Dank für Ihre Anregungen,

+3

Also ... seit wann ein ImageView einen 'checked' Zustand hat? –

+0

Ich dachte, das war, wofür der Selektor da war. Wenn die Bildansicht zum ersten Mal überprüft wird, wird sie rot angezeigt, um sie anzuzeigen. Wenn Sie erneut darauf klicken, wird es grün, um "aus" anzuzeigen. – ant2009

+1

Nun, ein ImageView ist dann nicht die Ansicht, die Sie verwenden möchten. Verwenden Sie stattdessen eine [CheckBox] (http://developer.android.com/reference/android/widget/CheckBox.html). Möglicherweise möchten Sie die Schaltfläche "button" anpassen. Mögliches Duplikat von: http://stackoverflow.com/questions/3192173/change-icons-of-checked-und-unched-for-checkbox-for-android –

Antwort

10

Wenn ich jedoch auf die Bildansicht klicke, passiert nichts.So

, wie @Zielony sagte, der Grund ist einfach: ImageView nicht unterstützt geprüft Staaten.

Jede Klasse von View unterstützt verschiedene Staaten erweitert: gedrückt, ausgewählt, konzentriert, überprüfbar (beachten Sie, dass nicht Zustand geprüft) etc. Aber geprüft besonderen Zustand befindet. Und nur wenige View s unterstützen sie: ToggleButton, Switch, RadioButton, CheckBox, CheckedTextView. Sie implementiert Checkable Schnittstelle.

Sie haben Varianten, wie Sie Ihren Fall zu lösen, aber es hängt davon ab, was genau Sie brauchen:

  1. Wenn Sie wirklich diese einfache Sache wollen

    So wird aus einer grünen Farbe angezeigt werden und auf wird eine rote Farbe an.

    können Sie CheckBox oder CheckedTextView beispielsweise verwenden. Selektor Erstellen Sie einfach:

    <selector xmlns:android="http://schemas.android.com/apk/res/android"> 
        <item android:drawable="<red_color>" android:state_checked="true" /> 
        <item android:drawable="<green_color>" /> 
    </selector> 
    

    und es

    <CheckBox 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:text="" 
        android:button="@null" 
        android:clickable="true" 
        android:background="<your_selector>"/> 
    
  2. Verwenden Sie anderen Zustand verwenden. Sie können verwenden state_activated (oder state_selected aber vorsichtig sein, denn ausgewählt transiente Eigenschaft ist)

    <selector xmlns:android="http://schemas.android.com/apk/res/android"> 
        <item android:drawable="<red_color>" android:state_activated="true" /> 
        <item android:drawable="<green_color>" /> 
    </selector> 
    

    und schalten diesen Zustand durch Code

    <your_image_view>.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         <your_image_view>.setActivated(!<your_image_view>.isActivated()); 
        } 
    }); 
    
  3. Ihre eigene überprüfbar Klasse schreiben . Sie können von anderen Menschen zu sehen, wie es zu tun ist:

    1. Official android implementation from old Contacts application

      public class CheckableImageView extends ImageView implements Checkable { 
          private boolean mChecked; 
      
          private static final int[] CHECKED_STATE_SET = { 
           android.R.attr.state_checked 
          }; 
      
          public CheckableImageView(Context context, AttributeSet attrs) { 
           super(context, attrs); 
          } 
      
          @Override 
          public int[] onCreateDrawableState(int extraSpace) { 
           final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
           if (isChecked()) { 
            mergeDrawableStates(drawableState, CHECKED_STATE_SET); 
           } 
           return drawableState; 
          } 
      
          public void toggle() { 
           setChecked(!mChecked); 
          } 
      
          public boolean isChecked() { 
           return mChecked; 
          } 
      
          public void setChecked(boolean checked) { 
           if (mChecked != checked) { 
            mChecked = checked; 
            refreshDrawableState(); 
           } 
          } 
      } 
      
    2. Other implementation in MultiChoiceAdapter

    3. Implementation with OnCheckedChangeListener and saved state, like CheckBox class und auch dies ist die beste Umsetzung ich je

      public class CheckableImageView extends ImageView implements Checkable { 
      
          private static final int[] checkedStateSet = { android.R.attr.state_checked }; 
      
          private boolean mChecked = false; 
          private OnCheckedChangeListener mOnCheckedChangeListener; 
      
          private boolean mBroadcasting; 
      
          public CheckableImageView(Context context) { 
           super(context); 
          } 
      
          public CheckableImageView(Context context, AttributeSet attrs) { 
           super(context, attrs); 
          } 
      
          public CheckableImageView(Context context, AttributeSet attrs, int defStyle) { 
           super(context, attrs, defStyle); 
          } 
      
          @Override 
          public boolean isChecked() { 
           return mChecked; 
          } 
      
          @Override 
          public boolean performClick() { 
           toggle(); 
           return super.performClick(); 
          } 
      
          @Override 
          public void toggle() { 
           setChecked(!mChecked); 
          } 
      
          @Override 
          public int[] onCreateDrawableState(int extraSpace) { 
           final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
           if (isChecked()) { 
            mergeDrawableStates(drawableState, checkedStateSet); 
           } 
           return drawableState; 
          } 
      
          @Override 
          public void setChecked(boolean checked) { 
           if (mChecked != checked) { 
            mChecked = checked; 
            refreshDrawableState(); 
      
            // Avoid infinite recursions if setChecked() is called from a listener 
            if (mBroadcasting) { 
             return; 
            } 
      
            mBroadcasting = true; 
            if (mOnCheckedChangeListener != null) { 
             mOnCheckedChangeListener.onCheckedChanged(this, mChecked); 
            } 
      
            mBroadcasting = false; 
           } 
          } 
      
          /** 
          * Register a callback to be invoked when the checked state of this button 
          * changes. 
          * 
          * @param listener the callback to call on checked state change 
          */ 
          public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { 
           mOnCheckedChangeListener = listener; 
          } 
      
          /** 
          * Interface definition for a callback to be invoked when the checked state 
          * of a compound button changed. 
          */ 
          public static interface OnCheckedChangeListener { 
           /** 
           * Called when the checked state of a compound button has changed. 
           * 
           * @param buttonView The compound button view whose state has changed. 
           * @param isChecked The new checked state of buttonView. 
           */ 
           void onCheckedChanged(CheckableImageView buttonView, boolean isChecked); 
          } 
      
          static class SavedState extends BaseSavedState { 
           boolean checked; 
      
           /** 
           * Constructor called from {@link CompoundButton#onSaveInstanceState()} 
           */ 
           SavedState(Parcelable superState) { 
            super(superState); 
           } 
      
           /** 
           * Constructor called from {@link #CREATOR} 
           */ 
           private SavedState(Parcel in) { 
            super(in); 
            checked = (Boolean) in.readValue(null); 
           } 
      
           @Override 
           public void writeToParcel(Parcel out, int flags) { 
            super.writeToParcel(out, flags); 
            out.writeValue(checked); 
           } 
      
           @Override 
           public String toString() { 
            return "CheckableImageView.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " checked=" + checked + "}"; 
           } 
      
           public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { 
            @Override 
            public SavedState createFromParcel(Parcel in) { 
             return new SavedState(in); 
            } 
      
            @Override 
            public SavedState[] newArray(int size) { 
             return new SavedState[size]; 
            } 
           }; 
          } 
      
          @Override 
          public Parcelable onSaveInstanceState() { 
           Parcelable superState = super.onSaveInstanceState(); 
           SavedState ss = new SavedState(superState); 
           ss.checked = isChecked(); 
           return ss; 
          } 
      
          @Override 
          public void onRestoreInstanceState(Parcelable state) { 
           SavedState ss = (SavedState) state; 
      
           super.onRestoreInstanceState(ss.getSuperState()); 
           setChecked(ss.checked); 
           requestLayout(); 
          } 
      } 
      
      gesehen habe

Diese Optionen, die zuerst in den Sinn kommen und eine gute Umsetzung haben.Sie können aber auch eigene Versionen erstellen oder einfache Variablen verwenden, um den Status zu speichern und manuell wie @ Chirag-Savsani zu wechseln, aber in diesem Fall müssten Sie auf die Verwendung von selector s verzichten.

+0

Die dritte Option ist definitiv der Weg zu gehen – Sree

+0

Option 2: Konvertiert von state_checked zu state_activated und funktioniert besser für meine Verwendung Fall. Vielen Dank! – user1652110

4

Sie können versuchen:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_selected ="false" 
      android:drawable="@drawable/bottom_left_border"/> 

    <item android:state_selected ="true" 
      android:drawable="@drawable/bottom_left_border_pressed"> 
    </item> 
</selector> 

und Java-Code:

imageview.setImageDrawable(getBaseContext().getResources().getDrawable(R.drawable....)); 

//set the click listener 

    imageview.setOnClickListener(new OnClickListener() { 

     public void onClick(View v) { 
      v.setSelected(!v.isSelected()); 
      //other code if need 
     } 

    }); 
8

Der Grund ist sehr einfach - Imageüberprüft nicht, für state_checked überhaupt. Kommentar von @ frank-n-stein ist der Antwort auf diese Frage am nächsten.

Sie haben zwei Möglichkeiten:

  • Verwendung eine Ansicht mit Unterstützung für state_checked (zum Beispiel eines CheckBox)
  • add state_checked zu Image

state_checked Unterstützung hinzufügen Sie überprüfbar implementieren Schnittstelle. Wie folgt aus:

public class CheckableImageView extends ImageView implements Checkable { 
    private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked}; 

    private boolean mChecked; 

    ... constructors 

    @Override 
    public void setChecked(boolean checked) { 
     if (mChecked != checked) { 
      mChecked = checked; 
      refreshDrawableState(); 
     } 
    } 

    @Override 
    public boolean isChecked() { 
     return mChecked; 
    } 

    @Override 
    public void toggle() { 
     setChecked(!mChecked); 
    } 

    @Override 
    public boolean performClick() { 
     toggle(); 
     return super.performClick(); 
    } 

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
     if (isChecked()) { 
      mergeDrawableStates(drawableState, CHECKED_STATE_SET); 
     } 

     return drawableState; 
    } 

    @Override 
    protected Parcelable onSaveInstanceState() { 
     SavedState result = new SavedState(super.onSaveInstanceState()); 
     result.checked = mChecked; 
     return result; 
    } 

    @Override 
    protected void onRestoreInstanceState(Parcelable state) { 
     if (!(state instanceof SavedState)) { 
      super.onRestoreInstanceState(state); 
      return; 
     } 

     SavedState ss = (SavedState) state; 
     super.onRestoreInstanceState(ss.getSuperState()); 

     setChecked(ss.checked); 
    } 

    protected static class SavedState extends BaseSavedState { 
     protected boolean checked; 

     protected SavedState(Parcelable superState) { 
      super(superState); 
     } 

     @Override 
     public void writeToParcel(Parcel out, int flags) { 
      super.writeToParcel(out, flags); 
      out.writeInt(checked ? 1 : 0); 
     } 

     public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { 
      public SavedState createFromParcel(Parcel in) { 
       return new SavedState(in); 
      } 

      public SavedState[] newArray(int size) { 
       return new SavedState[size]; 
      } 
     }; 

     private SavedState(Parcel in) { 
      super(in); 
      checked = in.readInt() == 1; 
     } 
    } 
} 

Der Code ist von hier: https://github.com/shomeser/AndroidLayoutSelector/blob/master/LayoutSelector/src/main/java/com/example/layoutselector/CheckableLinearLayout.java

3

Betrachten Sie Ihre Imageview: Button zu wechseln, da state_checked nicht auf Imageview beeinflussen. gesetzt Dann Hintergrund Ihres Schaltfläche, um Ihre selector_xml

<Button> 
... 
android:background="@drawable/your_selector_xml" 
</Button> 
7

Hallo ich auch dieses Szenario in meiner aktuellen Anwendung verwenden.

1) Mit CheckBox

Verwenden CheckBox mit android:button="@null" Eigenschaft wird Diese Eigenschaft Grenze von CheckBox entfernen und nur Ihre ziehbar Bilder anzuzeigen.

state_checked Eigenschaft funktioniert mit CheckBox

<CheckBox 
    android:id="@+id/imgDisplayCheckimg" 
    android:layout_width="wrap_contenrt" 
    android:layout_height="wrap_contenrt" 
    android:background="@drawable/display_checkbox" 
    android:button="@null" 
    android:checked="false" 
    android:clickable="true" /> 

Dies ist Drawable Datei display_checkbox.xml

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <!-- When selected, use red--> 
    <item android:drawable="@drawable/red_color" android:state_checked="true"/> 
    <!-- When not selected, use green--> 
    <item android:drawable="@drawable/green_color" android:state_checked="false"/> 
</selector> 

ersetzen red_color und green_color mit Ihrem ziehbar Namen.

2) Weltweit wird diese Variable ImageView

Deklarieren

boolean switchStatus = false; 

Ihre Image finden und unter Klick-Listener hinzufügen.

switchImageView.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 
     if(switchStatus == true) { 
      anonymousImage.setImageResource(R.drawable.red); 
      switchStatus = false; 
     } else { 
      anonymousImage.setImageResource(R.drawable.green); 
      switchStatus = true; 
     } 
    } 
}); 

ImageView in Layout-Datei.

<ImageView 
    android:id="@+id/switchImageView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/green" /> 

Namen ändern in grün und rot mit Ihrem ziehbar Namen.

1

Versuchen Sie dieses

< < < < < < Erste Way >>>>>>

1. eine color.xml erstellen in "Werte" Ordner unter „res "Ordner, wenn bereits erstellt, erstellen Sie es mit einem anderen Namen: color.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <drawable name="red">#FF0000</drawable> 
    <drawable name="green">#00FF00</drawable> 
    <drawable name="blue">#0000FF</drawable>  
</resources> 

2. nun einen Selektor wie on_off_selector.xml erstellen:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="false" android:drawable="@drawable/red" /> 
    <item android:state_pressed="true" android:drawable="@drawable/green"/> </selector> 

3. Nun setzen "android: Hintergrund" Eigentum Ihrer Image so etwas wie dieses Set auch android: clcikable = "wahr":

<ImageView 
    android:layout_width="100dp" 
    android:layout_height="100dp" 
    android:clickable="true" 
    android:id="@+id/imageView" 
    android:background="@drawable/on_off_selector" 
    /> 

< < < < < < < Second Way >>>>>>>

Eine Datei in ziehbar Ordner Make on_off_selecor.xml

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_pressed="false"> 
     <color android:color="#FF0000" /> 
    </item> 
    <item android:state_pressed="true"> 
     <color android:color="#00FF00" /> 
    </item> 
    <item> 
     <color android:color="#FF0000" /> 
    </item> 
</selector> 

Nun setzen "android: Hintergrund" Eigenschaft von Ihrem ImageView so etwas auch gesetzt android: clcikable = "wahr":

<ImageView 
    android:layout_width="100dp" 
    android:layout_height="100dp" 
    android:clickable="true" 
    android:id="@+id/imageView" 
    android:background="@drawable/on_off_selector" 
    /> 
Verwandte Themen