How can you tell when a layout has been drawn?

后端 未结 8 503
轻奢々
轻奢々 2020-11-22 08:07

I have a custom view that draws a scrollable bitmap to the screen. In order to initialize it, i need to pass in the size in pixels of the parent layout object. But during th

相关标签:
8条回答
  • 2020-11-22 08:20

    To avoid deprecated code and warnings you can use:

    view.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @SuppressWarnings("deprecation")
                @Override
                public void onGlobalLayout() {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        view.getViewTreeObserver()
                                .removeOnGlobalLayoutListener(this);
                    } else {
                        view.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                    }
                    yourFunctionHere();
                }
            });
    
    0 讨论(0)
  • 2020-11-22 08:33

    You can add a tree observer to the layout. This should return the correct width and height. onCreate() is called before the layout of the child views are done. So the width and height is not calculated yet. To get the height and width, put this on the onCreate() method:

        final LinearLayout layout = (LinearLayout) findViewById(R.id.YOUR_VIEW_ID);
        ViewTreeObserver vto = layout.getViewTreeObserver(); 
        vto.addOnGlobalLayoutListener (new OnGlobalLayoutListener() { 
            @Override 
            public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        layout.getViewTreeObserver()
                                .removeOnGlobalLayoutListener(this);
                    } else {
                        layout.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                    }
                int width  = layout.getMeasuredWidth();
                int height = layout.getMeasuredHeight(); 
    
            } 
        });
    
    0 讨论(0)
  • 2020-11-22 08:34

    An alternative to the usual methods is to hook into the drawing of the view.

    OnPreDrawListener is called many times when displaying a view, so there is no specific iteration where your view has valid measured width or height. This requires that you continually verify (view.getMeasuredWidth() <= 0) or set a limit to the number of times you check for a measuredWidth greater than zero.

    There is also a chance that the view will never be drawn, which may indicate other problems with your code.

    final View view = [ACQUIRE REFERENCE]; // Must be declared final for inner class
    ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
    viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            if (view.getMeasuredWidth() > 0) {     
                view.getViewTreeObserver().removeOnPreDrawListener(this);
                int width = view.getMeasuredWidth();
                int height = view.getMeasuredHeight();
                //Do something with width and height here!
            }
            return true; // Continue with the draw pass, as not to stop it
        }
    });
    
    0 讨论(0)
  • 2020-11-22 08:35

    Simply check it by calling post method on your layout or view

     view.post( new Runnable() {
         @Override
         public void run() {
            // your layout is now drawn completely , use it here.
          }
    });
    
    0 讨论(0)
  • 2020-11-22 08:38

    Better with kotlin extension functions

    inline fun View.waitForLayout(crossinline yourAction: () -> Unit) {
        val vto = viewTreeObserver
        vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                when {
                    vto.isAlive -> {
                        vto.removeOnGlobalLayoutListener(this)
                        yourAction()
                    }
                    else -> viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
            }
        })
    }
    
    0 讨论(0)
  • 2020-11-22 08:39

    Another answer is:
    Try checking the View dimensions at onWindowFocusChanged.

    0 讨论(0)
提交回复
热议问题