似乎无法从android中的视图中获取位图

时间:2015-03-16 19:14:36

标签: android android-layout bitmap android-view

我的问题类似于Android View.getDrawingCache returns null, only null中的问题。

我的代码用于处理方法

private Bitmap getBitmapFromView(View v) {
    v.setDrawingCacheEnabled(true);
    v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
    v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    v.buildDrawingCache(true);
    Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
    v.setDrawingCacheEnabled(false); // clear drawing cache
    return b;
}

但今天我更改了xml布局文件。由于更改,我在行Bitmap b = Bitmap.createBitmap(v.getDrawingCache())处获得了NullPointerException。所以我尝试将方法getBitmapFromView更改为

public static Bitmap loadBitmapFromView(View v) {
    Bitmap b = Bitmap.createBitmap(v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
    v.draw(c);
    return b;
}

但这并没有帮助。我在第一行得到了null。

情况是这样的:我正在尝试将视图转换为位图。但我这样做没有先在屏幕上显示视图。同样,在我更改xml布局文件的内容之前,这一切都已经过去了。这种变化甚至都不大。我只是移动了东西并删除了 - 是的,删除了一些子视图。

在任何情况下,我都知道我的布局文件没有问题,因为如果我愿意,我可以在屏幕上显示它;我作为故障排除的一部分做了。

有人建议使用处理程序来调用getDrawingCache()。如果这是答案,我该如何编写该代码?

更新

View view = activity.getLayoutInflater().inflate(R.layout.my_view, null, false);
    findViewsByIds(view);//where I inflate subviews and add content to them.

2 个答案:

答案 0 :(得分:0)

测量视图时执行createBitmapFromView。

public static void executeWhenViewMeasured(final View view, final Runnable runnable) {
    if(view.getMeasuredHeight() == 0 || view.getMeasuredWidth() == 0){
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                runnable.run();
                removeGlobalOnLayoutListener(view, this);
            }
        });
    } else {
        runnable.run();
    }
}

public static Bitmap createBitmapFromView(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static void removeGlobalOnLayoutListener(View view,
                                                ViewTreeObserver.OnGlobalLayoutListener listener) {
    try {
        view.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
    } catch (NoSuchMethodError e) {
        view.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
    }
}

executeWhenViewMeasured(view, new Runnable() {
            @Override
            public void run() {
                Bitmap bitmap = createBitmapFromView(view);
            }
        });

答案 1 :(得分:0)

由于您没有显示视图,因此在画布上绘制视图更容易。 您已经尝试这样做,但我会将两种方法合并为一种,而不使用绘图缓存。

private Bitmap getBitmapFromView(View v) {
    v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
    v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredWidth());
    Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredWidth(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    v.draw(c);
    return b;
}

如果没有布局视图,请检查MeasureSpec.UNSPECIFIED可能无法正常工作,因此您可能需要指定宽度和高度。