在Activity中获取View的高度(Android开发艺术探索学习笔记)

公羊新
2023-12-01

在onCreate里面,你是无法获得长宽值的,始终为0,为什么会这样呢?因为View的measure过程和Activity的生命周期不是同步的。所以下面来讨论一下在Activity中获取View的高度几种方法。

1.onWindowFocusChanged()
这个方法在onResume()和onPause()也会被调用,如果onResume()和onPause()被频繁调用,那么onWindowFocusChanged()也会被频繁调用。

    /**
     * Called when the current {@link Window} of the activity gains or loses
     * focus.  This is the best indicator of whether this activity is visible
     * to the user.  The default implementation clears the key tracking
     * state, so should always be called.
     * ……
     */
    public void onWindowFocusChanged(boolean hasFocus) {
    }

2.View.post()
通过post将一个Runnable投递到消息队列尾部。等Runnable被调用的时候,View已经初始化好了。

    /**
     * <p>Causes the Runnable to be added to the message queue.
     * The runnable will be run on the user interface thread.</p>
     */
    public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }
        // Assume that post will succeed later
        ViewRootImpl.getRunQueue().post(action);
        return true;
    }

3.ViewTreeObserver
使用OnGlobalLayoutListener(),监听布局完成,但是会多次调用,所以要及时remove掉Listener。

        final ViewTreeObserver viewTreeObserver = mView.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                viewTreeObserver .removeOnLayoutChangeListener(this);
            }
        });

类似的还有使用OnDrawListener()和OnPreDrawListener。

4.直接使用measure()

        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        mView.measure(w, h);
        int height = mView.getMeasuredHeight();
        int width = mView.getMeasuredWidth();
        System.out.println("measure width=" + width + " height=" + height);
 类似资料: