state_checked不会打开和关闭imageview

ant*_*009 18 android

Android Studio 2.0预览版

你好,

我有这个选择器连接到imageview.我想要imageview打开和关闭.因此off将显示绿色,并且将显示红色.

但是,当我点击时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>
Run Code Online (Sandbox Code Playgroud)

非常感谢任何建议,

Igo*_*nov 14

但是,当我点击imageview时没有任何反应.

因此,正如@Zielony所说,原因很简单:ImageView不支持检查状态.

从扩展的每个类View支持不同的状态:按下,选择,聚焦,可检查(注意未检查状态)等.但是检查是特殊状态.而只有少数View的支持它:ToggleButton,Switch,RadioButton,CheckBox,CheckedTextView.他们实现了Checkable界面.

你有变种如何解决你的情况,但它取决于你究竟需要什么:

  1. 如果你真的想要这个简单的事情

    因此off将显示绿色,并且将显示红色.

    你可以使用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>
    
    Run Code Online (Sandbox Code Playgroud)

    并使用它

    <CheckBox
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:text=""
        android:button="@null"
        android:clickable="true"
        android:background="<your_selector>"/>
    
    Run Code Online (Sandbox Code Playgroud)
  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>
    
    Run Code Online (Sandbox Code Playgroud)

    并通过代码切换此状态

    <your_image_view>.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            <your_image_view>.setActivated(!<your_image_view>.isActivated());
        }
    });
    
    Run Code Online (Sandbox Code Playgroud)
  3. 写你自己的可检查课程.你可以从其他人那里看到如何做到这一点:

    1. 旧联系人应用程序的官方android实现

      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();
              }
          }
      }
      
      Run Code Online (Sandbox Code Playgroud)
    2. MultiChoiceAdapter中的其他实现

    3. 与类OnCheckedChangeListener一样实现和保存状态,CheckBox这也是我见过的最好的实现

      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();
          }
      }
      
      Run Code Online (Sandbox Code Playgroud)

首先想到这个选项,并有一个很好的实现.但你也可以提出你自己的版本,或者使用简单的变量来保存状态和切换,如@ Chirag-Savsani所说,但在这种情况下你将不得不放弃使用selectors.


Zie*_*ony 8

原因很简单 - ImageView根本不检查state_checked.@ frank-n-stein的评论最接近这个问题的答案.

您有两种选择:

  • 使用支持state_checked的视图(例如CheckBox)
  • 将state_checked添加到ImageView

要添加state_checked支持,您必须实现Checkable接口.像这样:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

代码来自:https://github.com/shomeser/AndroidLayoutSelector/blob/master/LayoutSelector/src/main/java/com/example/layoutselector/CheckableLinearLayout.java


Chi*_*ani 7

您好我也在我当前的应用程序中使用此场景.

1)使用CheckBox

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" />
Run Code Online (Sandbox Code Playgroud)

这是Drawable文件 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>
Run Code Online (Sandbox Code Playgroud)

将red_color和green_color替换为可绘制的名称.

2)使用 ImageView

在全球范围内声明此变量

boolean switchStatus = false;
Run Code Online (Sandbox Code Playgroud)

找到你的ImageView并在下面添加Click Listener.

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;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

ImageView 在布局文件中.

<ImageView
    android:id="@+id/switchImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/green" />
Run Code Online (Sandbox Code Playgroud)

使用可绘制的名称更改绿色和红色的名称.