0

I am inflating a view using the call

final View view = mActivity.getLayoutInflater().inflate(R.layout.photo_view, null, false);

The view is being inflated for the sole purpose of turning it into a Bitmap.

The following call is not working. Now if I make the call inside a DialogFragment's onCreateView it works -- so I know the code snippet itself works. But if I am just inflating the view for Bitmap conversion then the method public void onGlobalLayout() is never called.

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
    if (viewTreeObserver.isAlive()) {
        Log.i(TAG, "waiting for right time");
        view.getViewTreeObserver().addOnGlobalLayoutListener(new
            ViewTreeObserver.OnGlobalLayoutListener() {
                @SuppressLint("NewApi")
                @Override
                public void onGlobalLayout() {

                    if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) {
                        int height = getDeviceHeight(mActivity);
                        int width = getDeviceWidth(mActivity);
                        LayoutParams layout = view.getLayoutParams();
                        layout.height = height;
                        layout.width = width;
                        view.setLayoutParams(layout);
                    }

                    doMyWork(view);
                    if (Utils.hasJellyBean()) {
                        view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    } else {
                        view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }

                }
            });
    }

I need this method because I want to have a non-zero dimension to create my bitmap from otherwise I get null for say, view.getDrawingCache(). So how do I force the execution of ViewTreeObserver.OnGlobalLayoutListener

Katedral Pillon
  • 14,534
  • 25
  • 99
  • 199

2 Answers2

2

Your view is not attached to window. Try call view.requestLayout() after onGlobalLayoutListener adding.

Denis Makovsky
  • 460
  • 7
  • 22
1

Your view is never attached to a window -- it will never be laid out by the framework. You will need to either attach it to a window (e.g. put it in your layout somewhere) or measure and lay it out manually.

int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

view.measure(widthSpec, heightSpec);
view.layout(view.getMeasuredWidth(), view.getMeasuredHeight());
Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
  • I can't figure where `getMeasuredWidth()` and `getMeasuredHeight()` are coming from for used inside `view.layout(getMeasuredWidth(), getMeasuredHeight())` – Katedral Pillon Mar 17 '15 at 03:23
  • Thanks for the help, but it made no difference. I still get NPE for `view.getDrawingCache()` – Katedral Pillon Mar 17 '15 at 03:41
  • I don't think drawing cache will work if it's not attached to a window. Just draw it straight to a canvas. Create a new bitmap of the view's size, create a new Canvas wrapping that bitmap, then call view.draw(canvas); – Kevin Coppock Mar 17 '15 at 03:43
  • I asked the bigger question at http://stackoverflow.com/questions/29085109/cannot-seem-to-get-bitmap-from-view-in-android. Maybe you can help from that point of view – Katedral Pillon Mar 17 '15 at 03:43