记忆沉重的椭圆形渐变 [英] Memory heavy oval gradient

查看:123
本文介绍了记忆沉重的椭圆形渐变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可能已经知道,无法使用常规Android API绘制椭圆形的径向渐变.

As you may know it is not possible to draw an oval radial gradient using regular Android API.

这是我想要实现的:

因此,我实现了此解决方案:在正方形位图上绘制规则的径向渐变,然后该位图将被视图本身拉伸(此处的想法是:https://stackoverflow.com/a/3543899/649910 )

So I implemented this solution: draw a regular radial gradient on a square bitmap and then this bitmap will get stretched by the view itself (idea found here: https://stackoverflow.com/a/3543899/649910)

这很好用,但是由于BitmapDrawable的使用,此解决方案需要大量内存(请参阅下面的实现详细信息).

This works great however this solution takes a lot of memory, because of BitmapDrawable usage (see implementation details below).

欢迎任何关于如何避免使用如此大的位图的想法!

Any ideas on how to avoid usage of such a big bitmap are welcome!

这是我的代码:

public class OvalGradientView extends ImageView {

    private Drawable defaultBackgroundDrawable;

    public OvalGradientView(Context context) {
        super(context);
        init();
    }

    public OvalGradientView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public OvalGradientView(Context context, AttributeSet attrs, int defStyleAttr, Paint paint) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setScaleType(ScaleType.FIT_XY);
        defaultBackgroundDrawable = getResources().getDrawable(R.drawable.default_background);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        int width = getWidth();
        int height = getHeight();
        Rect currentBounds = defaultBackgroundDrawable.getBounds();
        // check if we already have bitmap for these bounds
        if (currentBounds.right == width && currentBounds.bottom == height) {
            return;
        }
        // draw the drawable on square bitmap, it will be then stretched if needed to rectangular shape
        // as the view gets more rectangular
        defaultBackgroundDrawable.setBounds(0, 0, width, width);
        Bitmap defaultBackgroundBitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(defaultBackgroundBitmap);
        defaultBackgroundDrawable.draw(canvas);
        setImageBitmap(defaultBackgroundBitmap);
    }
}

这是可绘制的XML-default_background

And this is the drawable XML - default_background

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:startColor="#ffffff"
        android:endColor="#ff6600"
        android:gradientRadius="50%p"
        android:type="radial" />
</shape

推荐答案

我最终完成了此实现:

public class MyBackgroundView extends ImageView {

    public MyBackgroundView(Context context) {
        super(context);
    }

    public MyBackgroundView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyBackgroundView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    {
        setBackgroundResource(R.drawable.my_background);
        setScaleType(ScaleType.FIT_XY);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        if (!changed) {
            return;
        }

        int width = right - left;
        int height = bottom - top;
        float aspectRatio = (float) width / height;
        if (aspectRatio > 1f) {
            setScaleX(aspectRatio);
        } else {
            setScaleY(1 / aspectRatio);
        }
    }
}

其中my_background是:

where my_background is:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:startColor="@color/my_background_start_color"
        android:endColor="@color/my_background_end_color"
        android:gradientRadius="@fraction/my_background_gradient_radius_percent"
        android:type="radial" />
</shape>

此视图的宽度和高度均为match_parent.

Width and height of this view are both match_parent.

这篇关于记忆沉重的椭圆形渐变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆