android - state_checked 不会打开和关闭 imageview

标签 android

Android Studio 2.0 预览

你好,

我有这个连接到 imageview 的选择器。我想打开和关闭 imageview。所以 off 会显示绿色,on 会显示红色。

但是,当我单击 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>

非常感谢您的任何建议,

最佳答案

However, when I click the imageview nothing happens.

所以,正如 @Zielony 所说,原因很简单:ImageView 不支持 checked 状态。

View 扩展的每个类都支持不同的状态:pressedselectedfocusedcheckable (注意不是 checked 状态)等。但是 checked 是特殊状态。只有少数 View 支持它:ToggleButtonSwitchRadioButtonCheckBox , CheckedTextView。他们实现了Checkable接口(interface)。

你有不同的方法来解决你的问题,但这取决于你到底需要什么:

  1. 如果你真的想要这个简单的东西

    So off will display a green color and on will display a red color.

    例如,您可以使用 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,但要小心,因为 selected 是 transient 属性)

    <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 所说的那样手动切换,但在这种情况下,您将不得不放弃使用 选择器s.

关于android - state_checked 不会打开和关闭 imageview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33942116/

相关文章:

java - 即使正确的JSON JAVA Volley,凭证响应也无效

C#/.net 相当于 android 处理程序

android - 使用带有 GridLayoutManager 的 RecyclerView 的简单 Android 网格示例(如旧的 GridView)

android - 如何从项目中获取 MD5 签名?

java - Eclipse 当尝试从一个类运行到另一个类的方法时,它使我的应用程序崩溃

java - 蓝牙聊天示例和上下文参数

Android 广播接收器与服务

android - 在一个线程中使用等待和通知

Android Exoplayer AdaptiveTrackSelection 需要以高质量启动视频

java - makeToast 无法在另一个类中解析