14

我们为什么要使用ViewTreeObserver,请任何人解释一下吗?

在下面的代码creditsView中是TextView对象。通过整个代码,我了解到“这是根据条件隐藏一些文本”,但唯一的问题是我们为什么要使用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);
            }
        }
    });
4

2 回答 2

18

如果您还没有使用ViewTreeObservermainLayout.getRootView().getHeight()那么将简单地返回 0px,因为它还没有被布置(参见getWidth()and getHeight()ofView返回 0)。

因此,您要等到视图被测量、布局,然后从中获取宽度/高度值。当视图将在屏幕上布局时,将准确触发此回调。

于 2017-04-26T12:00:14.347 回答
8

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

这就是我在 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()
        }
    })
}

并从这样的活动中使用它

listThumb.addViewObserver {
 // your code
}

listThumb 在这种情况下是 recyclerview

于 2018-11-26T13:09:19.530 回答