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>
非常感谢任何建议,
答案 0 :(得分:13)
然而,当我点击imageview时没有任何反应。
因此,正如 @Zielony 所说,原因很简单:ImageView
不支持已检查状态。
从View
扩展的每个类都支持不同的状态:按,选择,专注,可检查(注意,不是已检查状态)等。但已检查是特殊状态。只有少数View
支持它:ToggleButton
,Switch
,RadioButton
,CheckBox
,CheckedTextView
。他们实施了Checkable
接口。
你有变种如何解决你的情况,但这取决于你究竟需要什么:
如果你真的想要这个简单的事情
关闭将显示绿色,并且将显示红色。
您可以使用CheckBox
或CheckedTextView
。只需创建选择器:
<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>"/>
使用其他状态。您可以使用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());
}
});
编写您自己的可检查类。您可以从其他人那里了解如何操作:
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();
}
}
}
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 所说,但在这种情况下你将不得不放弃使用{{1 }}第
答案 1 :(得分:8)
原因很简单 - ImageView根本不检查state_checked。 @ frank-n-stein的评论最接近这个问题的答案。
您有两种选择:
要添加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;
}
}
}
答案 2 :(得分:7)
您好我也在当前的应用程序中使用了这种情况。
1)使用CheckBox
将CheckBox
与android: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"
/>