Search code examples
javaandroid-studioscreenshotandroid-tablelayoutscrollable

Java Android Studio Screenshot A TableLayout


I am trying to get a screenshot of a scrollable table. The TableLayout has parent matching width/height and right/left padding. The TableRows width/height has wrap_content and textAlignment center.

After some work I got to this code:

private Bitmap getBitmapFromView(View view)
{
    view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

    Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(bitmap);
    canvas.drawColor(Color.WHITE);

    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    view.draw(canvas);

    return bitmap;
}

While it does get all the information , it doesn't get the padding and/or textAlignment correctly , displaying the text too close to each other.

And this is how it should look vs how it looks: Image

I also tried a different approach:

Bitmap bitmap = getBitmapFromView(TableLayout, TableLayout.getHeight(), TableLayout.getWidth());

private Bitmap getBitmapFromView(View view, int height, int width) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Drawable bgDrawable = view.getBackground();
        if (bgDrawable != null)
            bgDrawable.draw(canvas);
        else
            canvas.drawColor(Color.WHITE);
        view.draw(canvas);
        return bitmap;
    }

While this does keep the padding/alignment it always return every row but the last one (when adding new rows). So if i have 20 rows it returns only 19.

It also leaves a white space when i delete a row (where the deleted row was).

It seems like it doesn't update the TableLayout properly before getting the screenshot. I've tried using:

view.invalidate();
view.requestLayout();

But with no result.

In the first approach it gets all the data (when adding) and doesn't return white spaces where deleted rows are (when removing) but it has padding/alignment issues while in the second method it gets incomplete data.


Solution

  • The second method should work but only after the table finished the job.

    You can create a ViewTreeObserver.OnGlobalLayoutListener and put the screenshot code inside thus waiting for the table to finish the job.

    ViewTreeObserver.OnGlobalLayoutListener tableLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            ViewTreeObserver observer = yourTableLayout.getViewTreeObserver();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                observer.removeOnGlobalLayoutListener(this);
            } else {
                observer.removeGlobalOnLayoutListener(this);
            }
    
            //Your code here
        }
    };
    

    And you can create it by using

    yourTableLayout.getViewTreeObserver().addOnGlobalLayoutListener(tableLayoutListener);