我已经制作了以下ImageView,以支持选择器为“src”:
public class CheckableImageView extends ImageView implements Checkable { private boolean mChecked; private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked }; public CheckableImageView(final Context context,final AttributeSet attrs) { super(context,attrs); final TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.com_app_CheckableImageView,0); setChecked(a.getBoolean(R.styleable.com_app_CheckableImageView_com_app_checked,false)); a.recycle(); } @Override public int[] onCreateDrawableState(final int extraSpace) { final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); if (isChecked()) mergeDrawableStates(drawableState,CHECKED_STATE_SET); return drawableState; } @Override public void toggle() { setChecked(!mChecked); } @Override public boolean isChecked() { return mChecked; } public interface OnCheckStateListener { void onCheckStateChanged(boolean checked); } private OnCheckStateListener mOnCheckStateListener; public void setOnCheckStateListener(OnCheckStateListener onCheckStateListener) { mOnCheckStateListener = onCheckStateListener; } @Override public void setChecked(final boolean checked) { if (mChecked == checked) return; mChecked = checked; refreshDrawableState(); if (mOnCheckStateListener != null) mOnCheckStateListener.onCheckStateChanged(checked); } }
问题
上面的代码适用于普通选择器,它具有图像文件作为每个状态可绘制的项目.
事实上,它完全不适用于矢量绘图(使用“srcCompat”).相反,它显示一个空的内容.
这是我试过的:
<...CheckableImageView ... app:srcCompat="@drawable/selector"/>
而选择器(例如)是:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" android:drawable="@drawable/test"/> <item android:state_pressed="true" android:drawable="@drawable/test" /> <item android:drawable="@drawable/test2" /> </selector>
示例矢量drawable:
<?xml version="1.0" encoding="utf-8"?> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="48dp" android:height="48dp" android:viewportWidth="48" android:viewportHeight="48"> <path android:fillColor="#0000ff" android:strokeColor="#000000" android:pathData="M 0 0 H 48 V 48 H 0 V 0 Z" /> <path android:fillColor="#ff0000" android:strokeColor="#000000" android:pathData="M14.769224,32.692291l5.707315,-17.692275l3.073244,17.479182l6.585245,-16.413424l2.634209,16.200186l-4.170761,-8.526356l-5.048693,7.247362l-5.268419,-8.100027l-3.51214,9.805351z" /> </vector>
这个问题
为什么不起作用?我做了什么错了?我该如何解决?
解决方法
我试图发布有关它的错误报告,但Google将其标记为“UserError”,即使我没有看到它记录,或有任何形式的警告:
Working as intended. Vectors are not supported in containers unless@H_301_36@ you turn on@H_301_36@ AppComaptDelegate.setCompatVectorFromResourcesEnabled(true).
https://code.google.com/p/android/issues/detail?id=210745
因此,如果您看到一个未显示的选择器,或者导致此日志崩溃:
引起:android.content.res.Resources $NotFoundException:来自可绘制资源ID的文件res / drawable / selector.xml#0x7f02004f
你应该避免在选择器中使用vectorDrawable,或者避免使用vectorDrawables.useSupportLibrary = true行.
您可以使用AppComaptDelegate.setCompatVectorFromResourcesEnabled(true),但是according to the docs,这可能有问题(主要是内存/性能问题),建议不要使用它:
Sets whether vector drawables on older platforms (< API 21) can be@H_301_36@ used within DrawableContainer resources.
When enabled,AppCompat can intercept some drawable inflation from the@H_301_36@ framework,which enables implicit inflation of vector drawables within@H_301_36@ DrawableContainer resources. You can then use those drawables in@H_301_36@ places such as android:src on ImageView,or android:drawableLeft on@H_301_36@ TextView.
This feature defaults to disabled,since enabling it can cause issues@H_301_36@ with memory usage,and problems updating Configuration instances. If@H_301_36@ you update the configuration manually,then you probably do not want@H_301_36@ to enable this. You have been warned.
Even with this disabled,you can still use vector resources through@H_301_36@ setImageResource(int) and it’s app:srcCompat attribute. They can also@H_301_36@ be used in anything which AppComapt inflates for you,such as menu@H_301_36@ resources.
Please note: this only takes effect in Activities created after this call.