Transform View into Bitmap without using buildDrawingCache()

Asked

Viewed 75 times

1

I have a function that takes a view and creates a bitmap. follow the code:

public static Bitmap getBitmapFromView(Context context, View view) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
        view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
        view.buildDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);

        return bitmap;
    }

The problem is that "buildDrawingCache" apparently does not work on API 28 (Android 9).
Is there any way to make the view bitmap without using "buildDrawingCache"?

1 answer

2


Your code is a little "weird". Use the buildDrawingCache() but instead of taking advantage of the Bitmap it returns, creates a new one and uses a Canvas to fill it with the contents of view.

Use only the part that creates Bitmap with the dimensions of the View and a Canvas associated with it. Then ask the view to write your content in it.

public static Bitmap getViewBitmap(View view){

    //Cria um bitmap com as dimensões da view
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
            view.getHeight(),
            Bitmap.Config.ARGB_8888);

    //Cria um canvas para escrever no bitmap
    Canvas canvas = new Canvas(bitmap);

    //Pede à view que escreva o seu conteúdo no bitmap, usando o canvas
    //anteriormente criado.
    view.draw(canvas);

    return bitmap;
}

Note that the method cannot be called in onCreate(). Only after "Tree of views" has been created does the view have the specified content and dimensions.

Use it in the method onWindowFocusChanged()

private Bitmap viewBitmap;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if(viewBitmap == null){
        viewBitmap = getViewBitmap(View);
    }
}

or in a OnGlobalLayoutListener

view.getViewTreeObserver().addOnGlobalLayoutListener(new

     ViewTreeObserver.OnGlobalLayoutListener() {
         @Override
         public void onGlobalLayout() {

            //Remove o listenner para não ser novamente chamado.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                //noinspection deprecation
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
            viewBitmap = getViewBitmap(view);
         }
     });
  • 1

    I didn’t even know about DrawingCache, so much that I avoided giving an answer to the question. I just read in documentation that this cache is obsolete since API 11 and its use may compromise application performance.

  • 1

    Everything worked fine, I tested on Apis 26,27,28 and all the code worked. Just to cool what the ramaral had already said, do not try to use this code block inside the onCreate because it will not work.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.