VectorDrawable:如何在画布上定位?

Ers*_*man 10 android android-canvas android-vectordrawable

您好我的自定义视图:

MyCustomView extends View 
Run Code Online (Sandbox Code Playgroud)

我做了一个VectorDrawable

mMyVectorDrawable = VectorDrawableCompat.create(getContext().getResources(), R.drawable.ic_some_image, null);
Run Code Online (Sandbox Code Playgroud)

我已经设定了界限

mMyVectorDrawable.setBounds(0, 0, mMyVectorDrawable.getIntrinsicWidth(), mMyVectorDrawable.getIntrinsicHeight());
Run Code Online (Sandbox Code Playgroud)

我在画布上绘制它

mMyVectorDrawable.draw(canvas);
Run Code Online (Sandbox Code Playgroud)

我在0,0位置看到了图像

但我该如何定位呢?如何定位Rect,我认为前两个参数setBounds将是X和Y坐标的开始绘图,但这只会影响尺寸.

如何将矢量绘图放在画布上?

谢谢阅读

Dan*_*gen 12

您可以在将drawable绘制到其上之前翻译画布.

mMyVectorDrawable.setBounds(0, 0, width, height);
canvas.translate(dx, dy);
mMyVectorDrawable.draw(canvas);
Run Code Online (Sandbox Code Playgroud)

dxdy指定(0, 0)将绘制下一个drawable 的坐标的偏移量.

如果需要,您也可以在以后撤消翻译:

canvas.translate(-dx, -dy);
Run Code Online (Sandbox Code Playgroud)

  • 您可以在canvas之前的操作之前使用canvas.save(),而在操作之后使用canvas.restore()来执行"反向"转换 (8认同)

Ese*_*far 5

这个问题有点老了,但如果它可以帮助某人,我有一个基于这个的答案。

这个想法是使用以下方法获取矢量可绘制:

Drawable drawable = AppCompatDrawableManager.get().getDrawable(context, R.drawable.my_drawable);
Run Code Online (Sandbox Code Playgroud)

然后我们直接从这个 Drawable 中获取 Bitmap 大小我们想要保持质量。然后,因为我们有一个位图,所以我们可以把它画在我们想要的地方。

注意:在你的 build.gradle的defaultConfig部分,不要忘记把这一行放在retro-compatibility:

vectorDrawables.useSupportLibrary = true
Run Code Online (Sandbox Code Playgroud)

这是从 Drawable 中获取位图的代码:

/**
 * Extract the Bitmap from a Drawable and resize it to the expectedSize conserving the ratio.
 *
 * @param drawable   Drawable used to extract the Bitmap. Can be null.
 * @param expectSize Expected size for the Bitmap. Use {@link #DEFAULT_DRAWABLE_SIZE} to
 *                   keep the original {@link Drawable} size.
 * @return The Bitmap associated to the Drawable or null if the drawable was null.
 * @see <html><a href="/sf/answers/742051551/">Stackoverflow answer</a></html>
 */
public static Bitmap getBitmapFromDrawable(@Nullable Drawable drawable, int expectSize) {
    Bitmap bitmap;

    if (drawable == null) {
        return null;
    }

    if (drawable instanceof BitmapDrawable) {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        if (bitmapDrawable.getBitmap() != null) {
            return bitmapDrawable.getBitmap();
        }
    }

    if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
        bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
    } else {
        float ratio = (expectSize != DEFAULT_DRAWABLE_SIZE)
                ? calculateRatio(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), expectSize)
                : 1f;

        int width = (int) (drawable.getIntrinsicWidth() * ratio);
        int height = (int) (drawable.getIntrinsicHeight() * ratio);

        bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

/**
 * Calculate the ratio to multiply the Bitmap size with, for it to be the maximum size of
 * "expected".
 *
 * @param height   Original Bitmap height
 * @param width    Original Bitmap width
 * @param expected Expected maximum size.
 * @return If height and with equals 0, 1 is return. Otherwise the ratio is returned.
 * The ration is base on the greatest side so the image will always be the maximum size.
 */
public static float calculateRatio(int height, int width, int expected) {
    if (height == 0 && width == 0) {
        return 1f;
    }
    return (height > width)
            ? expected / (float) width
            : expected / (float) height;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

正如@pskink 所说,这工作正常:

setBounds(x, y, intrinsic_width + x, intrinsic_height + y)
Run Code Online (Sandbox Code Playgroud)