web-dev-qa-db-ja.com

VectorDrawable:キャンバスに配置する方法は?

私のカスタムビューの場合:

MyCustomView extends View 

VectorDrawableを作成しました

mMyVectorDrawable = VectorDrawableCompat.create(getContext().getResources(), R.drawable.ic_some_image, null);

私はその限界を設定しました

mMyVectorDrawable.setBounds(0, 0, mMyVectorDrawable.getIntrinsicWidth(), mMyVectorDrawable.getIntrinsicHeight());

そしてそれをキャンバスに描きます

mMyVectorDrawable.draw(canvas);

位置0,0に画像が表示されます

しかし、どうすればそれを配置できますか? Rectを配置するにはどうすればよいですか。setBoundsの最初の2つのパラメータは、描画を開始する場所のX座標とY座標になると思いましたが、これはサイズに影響します。

ベクタードローアブルをキャンバスに配置するにはどうすればよいですか?

10
Ersen Osman

ドローアブルをキャンバスに描画する前に、キャンバスを移動できます。

mMyVectorDrawable.setBounds(0, 0, width, height);
canvas.translate(dx, dy);
mMyVectorDrawable.draw(canvas);

dxおよびdyは、次のドローアブルが描画される座標(0, 0)からのオフセットを指定します。

必要に応じて、後で翻訳を元に戻すこともできます。

canvas.translate(-dx, -dy);
13
Danilo Bargen

質問は少し古いですが、誰かを助けることができれば、 これ に基づいて答えがあります。

アイデアは、以下を使用してベクトルを描画可能にすることです。

Drawable drawable = AppCompatDrawableManager.get().getDrawable(context, R.drawable.my_drawable);

次に、このDrawableから、品質を維持したいサイズのビットマップを直接取得します。次に、ビットマップがあるので、必要な場所に描画できます。

注:build.gradleのdefaultConfigセクションに、この行を忘れずに入力してくださいレトロ互換性のために:

vectorDrawables.useSupportLibrary = true

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="https://stackoverflow.com/a/10600736/1827254">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;
}
4
Eselfar

@pskinkが言ったように、これはうまく機能します:

setBounds(x, y, intrinsic_width + x, intrinsic_height + y)
1
mackerel