带圆角的AppWidget图像

时间:2014-09-16 20:06:10

标签: java android bitmap png android-appwidget

所以,我通过动画在我的应用程序的主布局中向用户显示的各种视图动画在我的应用程序中动态创建图像。

目前我在RelativeLayout中生成场景,将布局图像作为位图,然后将位图保存到SD,以便appwidget通过uri访问。

这一切都很有效,但是...在为appwidget图像创建圆角的过程中,我尝试使用我发现的这两个片段here.

我的问题:

是这个方法生成一个drawable(如果显示为drawable,它的圆角看起来很完美),但是我需要将这些透明角输出为图像文件。下面的CustomView中的drawToBitmap方法确实会生成位图图像,但角落是满的和方形的。

/**
 * shows a bitmap as if it had rounded corners. based on :
 * http://rahulswackyworld.blogspot.co.il/2013/04/android-drawables-with-rounded_7.html
 */
public class RoundedCornersDrawable extends BitmapDrawable {

    private final BitmapShader bitmapShader;
    private final Paint p;
    private final RectF rect;
    private final float borderRadius;

    public RoundedCornersDrawable(final Resources resources, final Bitmap bitmap, final float     borderRadius) {
        super(resources, bitmap);
        bitmapShader = new BitmapShader(getBitmap(), Shader.TileMode.CLAMP,     Shader.TileMode.CLAMP);
        final Bitmap b = getBitmap();
        p = getPaint();
        p.setAntiAlias(true);
        p.setShader(bitmapShader);
        final int w = b.getWidth(), h = b.getHeight();
        rect = new RectF(0, 0, w, h);
        this.borderRadius = borderRadius < 0 ? 0.15f * Math.min(w, h) : borderRadius;
    }

    @Override
    public void draw(final Canvas canvas) {
        canvas.drawRoundRect(rect, borderRadius, borderRadius, p);
    }
}

public class CustomView extends ImageView {
    private FrameLayout mMainContainer;
    private boolean mIsDirty=false;

    // TODO for each change of views/content, set mIsDirty to true and call invalidate

    @Override
    protected void onDraw(final Canvas canvas) {
        if (mIsDirty) {
            mIsDirty = false;
            drawContent();
            return;
        }
        super.onDraw(canvas);
    }

    /**
     * draws the view's content to a bitmap. code based on :
     * http://nadavfima.com/android-snippet-inflate-a-layout-draw-to-a-bitmap/
     */
    public static Bitmap drawToBitmap(final View viewToDrawFrom, final int width, final int height) {
        // Create a new bitmap and a new canvas using that bitmap
        final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bmp);
        viewToDrawFrom.setDrawingCacheEnabled(true);
        // Supply measurements
        viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(),     MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY));
        // Apply the measures so the layout would resize before drawing.
        viewToDrawFrom.layout(0, 0, viewToDrawFrom.getMeasuredWidth(),    viewToDrawFrom.getMeasuredHeight());
        // and now the bmp object will actually contain the requested layout
        canvas.drawBitmap(viewToDrawFrom.getDrawingCache(), 0, 0, new Paint());
        return bmp;
     }

    private void drawContent() {
        if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0)
            return;
        final Bitmap bitmap = drawToBitmap(mMainContainer, getMeasuredWidth(), getMeasuredHeight());
        final RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(),     bitmap, 15);
        setImageDrawable(drawable);
    }
}

据我所知,位图不包含图像中有透明圆角所需的alpha信息, 所以我尝试将文件保存为PNG,就像这样;

RCD_test是RoundedCornersDrawable

Bitmap bitmap = RCD_test.getBitmap();
bitmap.setHasAlpha(true);
OutputStream stream = new          
FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/test/screenshottest.png");
bitmap.compress(CompressFormat.PNG, 100, stream);
stream.close();

但无济于事。整个方法可能看起来很复杂,但这就是我想出来解决AppWidget的RemoteViews的限制。

我的问题:

如何获取此RoundedCornersDrawable,并将其导出为PNG文件,以正确描绘其美丽的透明角落?

提前感谢您的帮助,我对所有关于问题的不同方法的建议持开放态度!

2 个答案:

答案 0 :(得分:1)

可悲的是,AppWidgets在视图方面非常有限。您只能使用Android支持的视图。

原因是视图的代码需要在AppWidget的容器​​上运行,这是一个安全风险,因为您可以瞥见显示它的应用程序的私有数据。所以Google所做的就是你需要准备要展示的内容,当你完成后,告诉受限制的API如何展示AppWidget。

因此解决方案是将应该显示的图像刷新到imageView或类似的东西。 如果有很多准备工作,我建议在后台进行。

这完全取决于您的需求。

答案 1 :(得分:0)

除了这个问题:

  

'事实证明,我的AppWidget的大小正在削减图像   全程。剪裁它只是为了去除圆角,和   只是没那么明显被剪掉了。所以对任何人   遇到这个问题......所有这些方法都适用于此   目的(只是不要忘记让你的AppWidget足够大看到   结果)。'

<强>答案:

我发现在将RoundedCornersDrawable导出到PNG文件之前通过CustomView.drawToBitMap()方法传递RoundedCornersDrawable也很关键。

我希望有一天这一切都可以帮助有人在路上!