首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带矢量绘图的TransitionDrawable

带矢量绘图的TransitionDrawable
EN

Stack Overflow用户
提问于 2018-04-11 14:09:05
回答 3查看 1.5K关注 0票数 1

我在xml中定义了TransitionDrawable,如下所示:

transition.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_disabled" />
    <item android:drawable="@drawable/ic_enabled" />
</transition>

我使用它来激活状态更改复选框:

代码语言:javascript
复制
val stateDrawable = ContextCompat.getDrawable(this, R.drawable.transition) as TransitionDrawable
checkbox.buttonDrawable = stateDrawable
checkbox.setOnCheckedChangeListener { icon, checked -> 
    if (checked) {
        stateDrawable.startTransition(300) 
    } else {
        stateDrawable.reverseTransition(300)
    }
}

如果@drawable/ic_disabled@drawable/ic_enabledpng文件,那么一切都正常。但是,如果它们是向量可绘制的,则转换不起作用。我遗漏了什么?TransitionDrawable不支持矢量绘图吗?

EN

回答 3

Stack Overflow用户

发布于 2019-02-07 23:31:55

我知道这很古老,但我也有同样的问题.在添加到BitmapDrawable之前,必须将向量转换为TransitionDrawable。下面是一个例子

代码语言:javascript
复制
            TransitionDrawable td = new TransitionDrawable(new Drawable[]{
                    getBitmapDrawableFromVectorDrawable(this, R.drawable.vector1),
                    getBitmapDrawableFromVectorDrawable(this, R.drawable.vector2)
            });
            td.setCrossFadeEnabled(true); // probably want this

            // set as checkbox button drawable...

实用程序方法//见https://stackoverflow.com/a/38244327/114549

代码语言:javascript
复制
public static BitmapDrawable getBitmapDrawableFromVectorDrawable(Context context, int drawableId) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        return (BitmapDrawable) ContextCompat.getDrawable(context, drawableId);
    }
    return new BitmapDrawable(context.getResources(), getBitmapFromVectorDrawable(context, drawableId));
}

public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
    Drawable drawable = ContextCompat.getDrawable(context, drawableId);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        drawable = (DrawableCompat.wrap(drawable)).mutate();
    }

    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}
票数 4
EN

Stack Overflow用户

发布于 2018-10-24 15:07:24

因为我所想要的只是用淡色来改变图像,所以我实现了一个简单的TransitionDrawable版本,它似乎适用于固定大小的矢量绘图。

代码语言:javascript
复制
public class SimpleTransitionDrawable extends Drawable {
    private static final int TRANSITION_STARTING = 0;
    private static final int TRANSITION_RUNNING = 1;
    private static final int TRANSITION_NONE = 2;

    private int state = TRANSITION_NONE;

    private long startTimeMillis;
    private int duration;

    private @Nullable Drawable source;
    private Drawable target;

    public void setTarget(Drawable target) {
        this.source = this.target;
        this.target = target;
        target.setBounds(0, 0, target.getIntrinsicWidth(), target.getIntrinsicHeight());
    }

    public void startTransition(int durationMillis) {
        duration = durationMillis;
        state = TRANSITION_STARTING;
        invalidateSelf();
    }

    @Override
    public void draw(Canvas canvas) {
        int alpha;

        switch (state) {
            case TRANSITION_STARTING:
                startTimeMillis = SystemClock.uptimeMillis();
                alpha = 0;
                state = TRANSITION_RUNNING;
                break;

            case TRANSITION_RUNNING:
                float normalized = (float) (SystemClock.uptimeMillis() - startTimeMillis) / duration;
                alpha = (int) (0xff * Math.min(normalized, 1.0f));
                break;

            default:
                if (target == null) return;
                alpha = 0xff;
                break;
        }

        if (source != null && alpha < 0xff) {
            source.setAlpha(0xff - alpha);
            source.draw(canvas);
        }

        if (alpha > 0) {
            target.setAlpha(alpha);
            target.draw(canvas);
        }

        if (alpha == 0xff) {
            state = TRANSITION_NONE;
            return;
        }

        invalidateSelf();
    }

    @Override public void setAlpha(int alpha) {}

    @Override public void setColorFilter(ColorFilter colorFilter) {}

    @Override public int getOpacity() {return PixelFormat.TRANSLUCENT;}
}

将其初始化如下:

代码语言:javascript
复制
ImageView view = findViewById(R.id.image_view);
SimpleTransitionDrawable drawable = new SimpleTransitionDrawable();
view.setImageDrawable(drawable);

然后用淡色修改可绘制的:

代码语言:javascript
复制
drawable.setTarget(AppCompatResources.getDrawable(this, R.drawable.my_vector));
drawable.startTransition(350);
票数 2
EN

Stack Overflow用户

发布于 2022-01-13 16:51:03

遵循@aaronvargas https://stackoverflow.com/a/54583929/1508956的相同方法

我创建了一些扩展函数,它封装了实现并使可用性更容易

代码语言:javascript
复制
fun Drawable.getBitmapDrawableFromVectorDrawable(context: Context): BitmapDrawable {
    return BitmapDrawable(context.resources, getBitmapFromVectorDrawable())
}

fun Drawable.getBitmapFromVectorDrawable(): Bitmap {
    val bitmap = Bitmap.createBitmap(
        intrinsicWidth,
        intrinsicHeight, Bitmap.Config.ARGB_8888
    )

    val canvas = Canvas(bitmap)
    setBounds(0, 0, canvas.width, canvas.height)
    draw(canvas)

    return bitmap
}

fun ImageView.setTransitionDrawable(vectorID: Int, firstColor: Int, secondColor: Int): TransitionDrawable? {
    val drawables = arrayOfNulls<Drawable>(2)

    val firstDrawable = ContextCompat.getDrawable(context, vectorID) ?: return null
    DrawableCompat.setTint(firstDrawable, ContextCompat.getColor(context, firstColor))
    drawables[0] = firstDrawable.getBitmapDrawableFromVectorDrawable(context)

    val secondDrawable = ContextCompat.getDrawable(context, vectorID) ?: return null
    DrawableCompat.setTint(secondDrawable, ContextCompat.getColor(context, secondColor))
    drawables[1] = secondDrawable.getBitmapDrawableFromVectorDrawable(context)

    val transition = TransitionDrawable(drawables)
    transition.isCrossFadeEnabled = true
    setImageDrawable(transition)

    return transition
}

初始化:

代码语言:javascript
复制
val transition = imageView.setTransitionDrawable(resourceID, R.color.firstColor, R.color.secondColor)
transition?.startTransition(3000)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49777302

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档