2015-11-26 63 views
16

的Android 2.0工作室預覽state_checked不切換imageview的開啓和關閉

你好,

我有這個選擇器,連接到imageview。我想要打開和關閉imageview。所以關閉會顯示綠色,並會顯示紅色。

但是,當我點擊imageview沒有任何反應。我嘗試了state_pressed和state_checked的不同組合。現在它變得太混亂了。我在這裏錯過了什麼。

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

非常感謝您的任何建議,

+3

因此...自從一個ImageView有一個'checked'狀態? –

+0

我以爲那是選擇者在那裏。第一次檢查圖像視圖時,它將顯示紅色以指示開啓。再次點擊時,它會變成綠色,表示關閉。 – ant2009

+1

那麼,ImageView不是你想要使用的視圖,那麼。改爲使用[CheckBox](http://developer.android.com/reference/android/widget/CheckBox.html)。您可能想要自定義其「按鈕」可繪製。可能的重複:http://stackoverflow.com/questions/3192173/change-icons-of-checked-and-unchecked-for-checkbox-for-android –

回答

10

但是,當我點擊imageview時什麼也沒有發生。

所以,@Zielony說,原因很簡單:ImageView不支持檢查狀態。

每一類從View擴展支持不同的狀態:選擇集中可檢查按下(注意不是檢查狀態)等,但檢查是特殊狀態。並且只有幾個View支持它:ToggleButtonSwitch,RadioButton,CheckBox, CheckedTextView。他們實現了Checkable接口。

你也有變種如何解決你的情況,但是這取決於你所需要的東西:

  1. 如果你真的想這樣簡單的事情

    等客會顯示一個綠色和將顯示紅色。

    可以使用CheckBoxCheckedTextView例如。只要創建選擇:

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

    ,並用它

    <CheckBox 
        android:layout_width="50dp" 
        android:layout_height="50dp" 
        android:text="" 
        android:button="@null" 
        android:clickable="true" 
        android:background="<your_selector>"/> 
    
  2. 使用另一種狀態。您可以使用state_activated(或state_selected但是,要小心,因爲選擇是短暫的財產)

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

    ,並通過代碼

    <your_image_view>.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         <your_image_view>.setActivated(!<your_image_view>.isActivated()); 
        } 
    }); 
    
  3. 切換此狀態下寫自己的可選中的類 。您可以從其他人看到如何做到這一點:

    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,也這是我見過的

      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(); 
          } 
      } 
      
      最佳執行

這個選項首先浮現在腦海中,並且具有良好的實施。但你也可以拿出你自己的版本,或使用簡單的變量來保存狀態和切換手冊,如@ Chirag-Savsani說,但在這種情況下,你將不得不放棄使用selector s。

+0

第三個選項肯定是要走的路 – Sree

+0

選項2:從state_checked轉換爲state_activated並更適合我的使用案件。謝謝! – user1652110

4

你可以試試:

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

和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

的原因很簡單 - ImageView的不檢查爲state_checked。評論來自@ frank-n-stein最接近這個問題的答案。

你有兩個選擇:

  • 使用與支持視圖state_checked(例如複選框)
  • 附加state_checked到ImageView的

要添加state_checked支持,你必須實現可勾選接口。就像這樣:

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

的代碼是從這裏:https://github.com/shomeser/AndroidLayoutSelector/blob/master/LayoutSelector/src/main/java/com/example/layoutselector/CheckableLinearLayout.java

3

考慮到您的ImageView切換到按鈕,因爲state_checked上ImageView的不影響。 然後設定按鈕的背景,你的selector_xml

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

你好,我也是在我目前的應用程序中使用此方案。

1)使用複選框

使用CheckBoxandroid:button="@null"財產, 此屬性將刪除的CheckBox邊界,只顯示你的繪製圖像。

state_checked屬性將與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" /> 

這是繪製對象文件 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> 

與繪製名稱替換red_color和green_color工作。

2)使用ImageView

聲明這個全局變量來

boolean switchStatus = false; 

找到你的ImageView,並添加下面點擊監聽器。

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

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

將您的可繪製名稱更改爲綠色和紅色。

1

試試這個

< < < < < <第一種方式>>>>>>

「資源下創建 「數值」 文件夾中的color.xml 「文件夾(如果已經創建)使用其他名稱創建它: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.現在像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> 

現在設置「機器人:背景」 您的ImageView像這樣屬性還設置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" 
    /> 

< < < < < < <第二種方式>>>>>>>

請在繪製文件夾的文件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> 

現在設置「機器人:背景」你的ImageView屬性也是這樣設置的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" 
    />