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

前端之家收集整理的这篇文章主要介绍了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@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.

猜你在找的Android相关文章