2015-11-26 11 views
16

Android Studio 2.0 podglądustate_checked nie przełączać ImageView i wyłączanie

Witam,

mam ten przełącznik, który jest podłączony do imageview. Chcę włączać i wyłączać imageview. Więc wyłączy się zielony kolor, a na wyświetlaczu pojawi się czerwony kolor.

Jednak po kliknięciu na imageview nic się nie dzieje. Próbowałem różnych kombinacji state_pressed i state_checked. A teraz staje się zbyt zagmatwany. Czego tu mi brakuje?

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

Wielkie dzięki za wszelkie sugestie,

+3

Więc ... od kiedy ImageView ma stan "sprawdzony"? –

+0

Myślałem, że to właśnie był selektor. Gdy obraz jest sprawdzany po raz pierwszy, będzie czerwony, aby wskazywać na. A po ponownym kliknięciu zmieni kolor na zielony, aby wyłączyć. – ant2009

+1

Cóż, ImageView nie jest Widok, który chcesz użyć, a następnie. Zamiast tego użyj [CheckBox] (http://developer.android.com/reference/android/widget/CheckBox.html). Możesz spersonalizować swój "draw" przycisku. Możliwy duplikat: http://stackoverflow.com/questions/3192173/change-icons-of-checked-and-unchecked-for-checkbox-for-android –

Odpowiedz

10

Jednak po kliknięciu obrazu nic się nie dzieje.

Tak, jak @Zielony powiedział, powód jest prosty: ImageView nieobsługiwane sprawdzone stany.

Każda klasa przedłużony z View obsługuje różne stany: wciśnięty, wybrany, koncentruje, dostępne do kontroli (zauważ, że to nie sprawdzone stan) itd. Ale sprawdzone jest szczególny stan. I tylko kilka z nich obsługuje: , Switch, RadioButton, CheckBox, CheckedTextView. Wdrożyli interfejs Checkable.

Masz warianty, jak rozwiązać sprawę, ale to zależy od tego, co dokładnie trzeba:

  1. Jeśli naprawdę chcesz tego prosta rzecz

    Tak od wyświetla kolor zielony, a na wyświetli czerwony kolor.

    można używać CheckBox lub CheckedTextView na przykład. Wystarczy utworzyć selektora:

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

    i używać go

    <CheckBox 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:text="" 
        android:button="@null" 
        android:clickable="true" 
        android:background="<your_selector>"/> 
    
  2. wykorzystywać inne państwo. Można używać state_activated (lub state_selected ale należy zachować ostrożność, ponieważ wybrany jest przemijające własność)

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

    i włączyć ten stan kodem

    <your_image_view>.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         <your_image_view>.setActivated(!<your_image_view>.isActivated()); 
        } 
    }); 
    
  3. Napisz Rejestrowalne klasę . Można zobaczyć od innych ludzi, jak to zrobić:

    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 i również jest to najlepsza realizacja kiedykolwiek widziałem

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

Te opcje, które przychodzą na myśl po pierwsze i mają dobrą implementację.Ale możesz też wymyślić własne wersje lub użyć prostych zmiennych do zapisania stanu i przełączania manualnego, np. @ Chirag-Savsani, ale w takim przypadku musisz zrezygnować z używania selector s.

+0

Trzecia opcja to zdecydowanie droga do przejścia – Sree

+0

Opcja 2: Konwertowana z sprawdzania stanu do stanu_aktywnego i działa lepiej dla mojego użytku walizka. Dzięki! – user1652110

4

Można spróbować:

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

i kod Java:

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

Powód jest bardzo prosty - ImageView nie sprawdza dla stanu state_checked w ogóle. Komentarz @ frank-n-stein jest najbliższy odpowiedzi na to pytanie.

Masz dwie opcje:

  • używać widok ze wsparciem dla state_checked (na przykład pole wyboru)
  • add state_checked do ImageView

Aby dodać state_checked wsparcia trzeba wdrożyć Rejestrowalne berło. Tak:

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

Kod jest stąd: https://github.com/shomeser/AndroidLayoutSelector/blob/master/LayoutSelector/src/main/java/com/example/layoutselector/CheckableLinearLayout.java

3

Rozważmy aby przełączyć ImageView do Buttona od state_checked nie wpływa na ImageView. następnie ustaw Button tło do selector_xml

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

Witam Używam również ten scenariusz w moim bieżącej aplikacji.

1) Korzystanie z CheckBox

Używaj CheckBox z android:button="@null" nieruchomości, Ta nieruchomość usunie granicy CheckBox i wyświetlać tylko swoje rozciągliwej obrazów.

state_checked nieruchomość będzie współpracować z 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" /> 

To rozciągliwej plik 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> 

Wymień red_color i green_color z rozciągliwej nazwy.

2) Korzystanie ImageView

oświadczam, zmienna ta Globalnie

boolean switchStatus = false; 

Znajdź ImageView i dodaj poniżej Click słuchacza.

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 w pliku układu.

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

Zmień nazwę na zielony i czerwony z rozciągliwej nazwy.

1

próbować ten jeden

< < < < < < Pierwszy sposób >>>>>>

1. Tworzenie color.xml w "wartości" pod folderze „res "folder, jeśli jest już utworzony, stwórz go z inną nazwą: 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. teraz utworzyć selektor jak on_off_selector.xml:

<?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. Teraz ustaw "android: tło" własność swojej ImageView coś takiego również ustawić Android: clcikable = "true":

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

< < < < < < < Drugi sposób >>>>>>>

stworzyć plik w folderze rozciągliwej 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> 

Teraz ustaw "android: tło" własność twojego ImageView coś podobnego również ustawić android: clcikable = "true":

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