android – 如何拥有vector drawables的选择器?

背景

我已经制作了以下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.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...