为什么我们使用 ViewTreeObserver#addOnGlobalLayoutListener()

Why we use ViewTreeObserver#addOnGlobalLayoutListener()

为什么我们使用ViewTreeObserver,谁能解释一下?

在下面的代码中 creditsViewTextView 对象。通过这整个代码,我理解 "this is to hide some text based on condition",但唯一的问题是我们为什么使用 ViewTreeObserver?

mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int heightDiff = mainLayout.getRootView().getHeight() - mainLayout.getHeight();

            if (heightDiff > 100) {
                Utils.appLogger("MyActivity", "keyboard opened");
                creditsView.setVisibility(View.GONE);
            }

            if (heightDiff < 100) {
                Utils.appLogger("MyActivity", "keyboard closed");
                creditsView.setVisibility(View.VISIBLE);
            }
        }
    });

如果您没有使用 ViewTreeObserver,那么 mainLayout.getRootView().getHeight() 将只是 return 0px,因为它还没有被布置(参见 getWidth() and getHeight() of View returns 0)。

因此,您要等到视图被测量、布局,然后您才能从中获取 width/height 值。当视图将要在屏幕上布局时,将触发此回调。

不知道为什么,但这是我搜索 KOTLIN 时显示给我的第一页,在通过 Lamda 后我无法删除 listner。

这就是我在 kotlin 中的做法

tvLoginWith.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
        override fun onGlobalLayout() {
            tvLoginWith.viewTreeObserver.removeOnGlobalLayoutListener(this)
            tvLogin.layoutParams.width = tvLoginWith.width
            tvLogin.requestLayout()
        }
    })

在 kotlin 中执行此操作的好方法(可重用) 像这样创建扩展

fun ViewGroup.addViewObserver(function: () -> Unit) {
    val view = this
    view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            view.viewTreeObserver.removeOnGlobalLayoutListener(this)
            function.invoke()
        }
    })
}

并像这样从 activity 使用它

listThumb.addViewObserver {
 // your code
}

listThumb 在这种情况下是 recyclerview