我已经制作了以下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
you turn on
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
used within DrawableContainer resources.When enabled,AppCompat can intercept some drawable inflation from the
framework,which enables implicit inflation of vector drawables within
DrawableContainer resources. You can then use those drawables in
places such as android:src on ImageView,or android:drawableLeft on
TextView.This feature defaults to disabled,since enabling it can cause issues
with memory usage,and problems updating Configuration instances. If
you update the configuration manually,then you probably do not want
to enable this. You have been warned.Even with this disabled,you can still use vector resources through
setImageResource(int) and it’s app:srcCompat attribute. They can also
be used in anything which AppComapt inflates for you,such as menu
resources.Please note: this only takes effect in Activities created after this call.