我想计算NavigationBar的高度。我看过这个演示文稿:https://chris.banes.me/talks/2017/becoming-a-master-window-fitter-nyc/
因此,我尝试使用方法View.setOnApplyWindowInsetsListener()
。
但是,由于某种原因,它从未被调用。
有人知道为什么吗?有什么限制吗?
我试图这样使用它:
navBarOverlay.setOnApplyWindowInsetsListener { v, insets ->
Timber.i("BOTTOM = ${insets.systemWindowInsetBottom}")
return@setOnApplyWindowInsetsListener insets
}
请注意,我的根目录布局是ConstraintLayout
。
答案 0 :(得分:0)
我不得不(而且我想应该)在某个适当的时间显式调用requestApplyInsets()来使监听器受到打击。
请查看本文以获取一些可能的提示:https://medium.com/androiddevelopers/windowinsets-listeners-to-layouts-8f9ccc8fa4d1
答案 1 :(得分:0)
在我的应用中,它只会被调用一次,而不是每次都被调用。因此,在一次调用中,我将widnowInsets保存到一个全局变量中,以在整个应用程序中使用它。
答案 2 :(得分:0)
我遇到了同样的问题。
如果您的根视图为ConstraintLayout且包含android:fitsSystemWindows =“ true” attr,则该视图使用onApplyWindowInsets回调。 因此,如果您在子视图上设置onApplyWindowInsets,则它们永远不会获得onApplyWindowInsets回调。
或者检查您的父视图是否使用了回调。
答案 3 :(得分:0)
我的解决方案是在navBarOverlay.rootView
上调用它。
答案 4 :(得分:0)
这是我观察到的;换句话说,您的经历可能会有所不同。
[Layout for Activity]
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" <--
tools:context=".MyAppActivity">
...
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
最外面的布局中的通知android:fitsSystemWindows="true"
。只要有,setOnApplyWindowInsetsListener()
就会被调用。
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
ViewCompat.setOnApplyWindowInsetsListener(fab) { view, insets ->
...
insets
}
}
或者,如果您要使用“全屏”,这意味着您希望将布局扩展到状态栏和导航栏,则可以执行以下操作。
override fun onCreate(savedInstanceState: Bundle?) {
...
WindowCompat.setDecorFitsSystemWindows(window, false) <--
ViewCompat.setOnApplyWindowInsetsListener(fab) { view, insets ->
...
insets
}
}
使用“片段”时,只要“活动”(包含片段)在最外面的布局中具有fitsSystemWindows
或将“活动”设置为全屏显示,该思想同样适用。
答案 5 :(得分:0)
使用CollapsingToolbarLayout
时遇到了这个问题,问题是CollapsingToolbarLayout
不调用插入侦听器,如果您有CollapsingToolbarLayout
,则此组件之后的所有其他视图插入不会被触发。如果是这样,请通过调用
CollapsingToolbarLayout
中删除监听器
ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, null)
如果您不CollapsingToolbarLayout
,那么其他一些视图会阻止插图在视图之间传递。
或者您已经食用了它们,我想您没有这样做)
答案 6 :(得分:0)
- willvincent/laravel-rateable[2.2.0, ..., 2.2.1] require illuminate/support ^6.0|^7.0 -> found illuminate/support[v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev] but it conflicts with another require.
- Root composer.json requires willvincent/laravel-rateable ^2.2 -> satisfiable by willvincent/laravel-rateable[2.2.0, 2.2.1].
中也存在一个错误,它阻止兄弟姐妹接收插图,您可以在issues github link中看到它。解决方案之一是将CollapsingToolbarLayout
放在xml其他视图的下面,以便他们接收插图。
答案 7 :(得分:0)
我使用 this 答案使用了以下解决方案:
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(android.R.id.content)
) { _: View?, insets: WindowInsetsCompat ->
navigationBarHeight = insets.systemWindowInsetBottom
insets
}
答案 8 :(得分:0)
将 ViewCompat.setOnApplyWindowInsetsListener
放入 onResume
对我使用了约束布局。
@Override
public void onResume() {
super.onResume();
ViewCompat.setOnApplyWindowInsetsListener(requireActivity().getWindow().getDecorView(), (v, insets) -> {
boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime());
int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
return insets;
});
}
答案 9 :(得分:0)
我在 API 30 上遇到了类似的问题。 要使 setOnApplyWindowInsetsListener() 工作,您必须确保您的活动处于全屏模式。您可以使用以下方法来做到这一点
WindowCompat.setDecorFitsSystemWindows(activity.window, false) //this is backward compatible version
还要确保您没有在任何地方使用以下方法来设置 UI 标志
View.setSystemUiVisibility(int visibility)
答案 10 :(得分:0)
我在我的项目中使用了以下解决方案,它就像一个魅力。
val decorView: View = requireActivity().window.decorView
val rootView = decorView.findViewById<View>(android.R.id.content) as ViewGroup
ViewCompat.setOnApplyWindowInsetsListener(rootView) { _, insets ->
val isKeyboardVisible = isKeyboardVisible(insets)
Timber.d("isKeyboardVisible: $isKeyboardVisible")
// Do something with isKeyboardVisible
insets
}
private fun isKeyboardVisible(insets: WindowInsetsCompat): Boolean {
val systemWindow = insets.systemWindowInsets
val rootStable = insets.stableInsets
if (systemWindow.bottom > rootStable.bottom) {
// This handles the adjustResize case on < API 30, since
// systemWindow.bottom is probably going to be the IME
return true
}
return false
}
在 Android API 中使用 setWindowInsetsAnimationCallback
而不是 setOnApplyWindowInsetsListener
> 30