1

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.

Vasil3
  • 100
  • 7
  • You really should not be calling layout or measure. It will screw up the placement of the view inside the parent. Which is probably part of your spacing issues. – Gabe Sechan Jun 15 '21 at 05:53
  • Does this answer your question? [How to render an android view to canvas WITHOUT rendering it first (i.e. without full layout)](https://stackoverflow.com/questions/60582424/how-to-render-an-android-view-to-canvas-without-rendering-it-first-i-e-without) – Andrew Jun 16 '21 at 19:37

1 Answers1

2

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);
Robert Stan
  • 326
  • 1
  • 2
  • 7