如何拥有一个矢量图选择器?

8

背景

我制作了以下 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, 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>

示例矢量图形:

<?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>

问题

为什么它不起作用?我做错了什么?我该如何修复它?


可能是Android Selector Drawable with VectorDrawables srcCompat的重复问题。 - Trenton McKinney
3个回答

15

看起来,这是支持库的一个bug,并且没有任何文档对其进行说明。

我尝试提交了一个关于它的Bug报告,但Google将其标记为“UserError”,尽管我没有看到它有任何文件记录或任何警告:

正常工作。除非您打开AppComaptDelegate.setCompatVectorFromResourcesEnabled(true),否则容器中不支持向量。

https://code.google.com/p/android/issues/detail?id=210745

因此,如果您看到一个选择器没有显示,或者导致这个日志崩溃:

Caused by: android.content.res.Resources$NotFoundException: File res/drawable/selector.xml from drawable resource ID #0x7f02004f

您应该避免在选择器内使用vectorDrawable,或避免使用vectorDrawables.useSupportLibrary=true这行代码.

您可以使用AppComaptDelegate.setCompatVectorFromResourcesEnabled(true),但根据文档(按照文档),这可能会出现错误(主要是内存/性能问题),不建议使用:

设置旧平台(< API 21)上的矢量可绘制是否可以在DrawableContainer资源内使用。

启用时,AppCompat可以拦截一些来自框架的drawable膨胀,从而启用DrawableContainer资源内的矢量隐式膨胀。然后,您可以在ImageView上的android:src或TextView上的android:drawableLeft等位置中使用这些drawable。

此功能默认禁用,因为启用它可能会导致内存使用问题,并且更新Configuration实例时可能会出现问题。如果手动更新配置,则可能不想启用此选项。你被警告了。

即使禁用了此功能,您仍然可以通过setImageResource(int)和其app:srcCompat属性使用矢量资源。它们也可以在AppCompat为您填充的任何内容中使用,例如菜单资源。

请注意:此设置仅对在此调用后创建的Activity生效。


0

我只是使用以下的XML就实现了它

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/ic_icons8_download_from_the_cloudwhite" android:state_focused="false" android:state_pressed="false" />
  <item android:drawable="@drawable/ic_download_from_the_cloudclicked" android:state_focused="true" android:state_pressed="true" />
  <item android:drawable="@drawable/ic_download_from_the_cloudclicked" android:state_focused="false" android:state_pressed="true" />
  <item android:drawable="@drawable/ic_download_from_the_cloudclicked" android:state_focused="false" />
</selector>

希望这能对有同样问题的人有所帮助。

-2

只需创建具有更改颜色的xml。并在运行时为按钮设置所选颜色可绘制。


1
这与问题无关。选择器可以做更多的事情。 - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接