Android 记忆重椭圆梯度

Android 记忆重椭圆梯度,android,bitmap,gradient,android-bitmap,android-memory,Android,Bitmap,Gradient,Android Bitmap,Android Memory,您可能知道,使用常规Android API不可能绘制椭圆形径向渐变 这就是我想要实现的目标: 所以我实现了这个解决方案:在一个正方形位图上画一个规则的径向渐变,然后这个位图会被视图本身拉伸(这里的想法:) 这非常有效,但是由于BitmapDrawable的使用,此解决方案占用了大量内存(请参见下面的实现细节) 欢迎提供任何有关如何避免使用如此大位图的想法 这是我的代码: public class OvalGradientView extends ImageView { private

您可能知道,使用常规Android API不可能绘制椭圆形径向渐变

这就是我想要实现的目标:

所以我实现了这个解决方案:在一个正方形位图上画一个规则的径向渐变,然后这个位图会被视图本身拉伸(这里的想法:)

这非常有效,但是由于BitmapDrawable的使用,此解决方案占用了大量内存(请参见下面的实现细节)

欢迎提供任何有关如何避免使用如此大位图的想法

这是我的代码:

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\u背景

<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


我不相信自己有能力创建这样的位图,特别是如果它们是全屏的。为什么不将xml形状作为背景应用于xml中的容器视图呢?如果宽度和高度与父视图匹配,则它将拉伸到视图的比例

public class OvalGradientView extends ImageView {
    public OvalGradientView(Context context, AttributeSet attrs) {
        super(context, attrs);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_sexy_gradient, this, true);
    }
}
my_sexy_gradient.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@drawable/default_background"/>

我不相信自己有能力创建这样的位图,特别是如果它们是全屏的。为什么不将xml形状作为背景应用于xml中的容器视图呢?如果宽度和高度与父视图匹配,则它将拉伸到视图的比例

public class OvalGradientView extends ImageView {
    public OvalGradientView(Context context, AttributeSet attrs) {
        super(context, attrs);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_sexy_gradient, this, true);
    }
}
my_sexy_gradient.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@drawable/default_background"/>

我最终实现了以下功能:

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);
        }
    }
}
我的大学背景是:

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


此视图的宽度和高度都与父视图匹配。

我最终实现了以下功能:

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);
        }
    }
}
我的大学背景是:

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

此视图的宽度和高度都与父视图匹配