state_checked没有打开和关闭imageview

时间:2015-11-26 15:24:31

标签: 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>

非常感谢任何建议,

6 个答案:

答案 0 :(得分:13)

  

然而,当我点击imageview时没有任何反应。

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

View扩展的每个类都支持不同的状态:选择专注可检查(注意,不是已检查状态)等。但已检查是特殊状态。只有少数View支持它:ToggleButtonSwitchRadioButtonCheckBoxCheckedTextView。他们实施了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();
          }
      }
      
  4. 首先想到这些选项并且具有良好的实现。但你也可以提出你自己的版本,或使用简单的变量来保存状态和切换,如 @ Chirag-Savsani 所说,但在这种情况下你将不得不放弃使用{{1 }}第

答案 1 :(得分: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;
        }
    }
}

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

答案 2 :(得分: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" />

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

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

2)使用ImageView

全球声明此变量

boolean switchStatus = false;

找到您的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;
        }
    }
});
布局文件中

ImageView

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

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

答案 3 :(得分:4)

您可以尝试:

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
        }

    });

和java代码:

Words

答案 4 :(得分:3)

考虑将imageView切换为Button,因为state_checked对imageView没有影响。 然后将按钮的背景设置为selector_xml

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

答案 5 :(得分:1)

试试这个

<强>&LT;&LT;&LT;&LT;&LT;&LT;第一种方式&gt;&gt;&gt;&gt;&gt;&gt;&gt;

1。在&#34;值&#34;中创建一个color.xml &#34; res&#34;下的文件夹文件夹(如果已创建)使用其他名称创建它: 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>

3。现在设置你的ImageView的&#34; android:background&#34; 属性也设置为 android:clcikable =&#34真&#34;

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

<强>&LT;&LT;&LT;&LT;&LT;&LT;&LT;第二种方式&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;

在可绘制文件夹 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的&#34; android:background&#34; 属性也设置为 android:clcikable =&#34; true&#34;

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