我开始了一个新项目。我读过那个单一的活动,许多片段是一种常见的推荐方法。我有一个 MainActivity 和 3 个片段。此设置仅来自最新的 Android Studio 中的“基本项目”模板。
我的目标是让 AppBar 在向下滚动时隐藏在其中一个片段上,这在应用程序中很常见,此外 FAB 在执行此操作时正确显示并在 Snackbar 出现时向上移动。我的 CoordinatorLayout 和 AppBarLayout>Toolbar 在 MainActivity 中,而 FAB 和 Recycler 在 fragment 中。
在处理此问题的过程中,我设法使 AppBar 覆盖了页面顶部和/或页面底部太低并切断了内容。这些是我的观点(为简洁起见缩短):
主要活动
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<AppBarLayout android:theme="@style/Theme.DynamicGPTChat.AppBarOverlay">
<androidx.appcompat.widget.Toolbar app:popupTheme="@style/Theme.DynamicGPTChat.PopupOverlay" />
</AppBarLayout>
<include layout="@layout/content_main" />
<!-- a floating action button here does work, but all the scroll issues still persist.
the only page it's needed on has a click listener -->
<!-- com.google.android.material.floatingactionbutton.FloatingActionButton -->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_main
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<fragment android:id="@+id/nav_host_fragment_content_main"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/nav_graph"/>
</androidx.constraintlayout.widget.ConstraintLayout>
片段_滚动
<ConstraintLayout>
<RecyclerView />
<com.google.android.material.floatingactionbutton.FloatingActionButton />
</ConstraintLayout>
片段_输入
<ConstraintLayout>
<RecyclerView />
<TextInputLayout app:layout_constraintBottom_toBottomOf="parent">
<TextInputEditText />
</TextInputLayout>
<MaterialButton app:layout_constraintTop_toTopOf="@+id/prompt_input_layout" app:layout_constraintBottom_toBottomOf="@+id/prompt_input_layout" />
</ConstraintLayout>
如果我将
layout_scrollFlags
添加到 AppBarLayout,那么 fragment_scroll
主要起作用。 FAB 反应不正确,它会下沉,直到我向下滚动时才能看到最上面的部分。但是 fragment_input 限制在底部的项目在底部下方,所以我只能看到顶部位,而在最后一个只是一堆输入的片段上,底部项目不再可见。我很确定这是因为它隐藏 AppBar 的方式使页面高了一点。
我尝试删除 Coordinator 布局上的
appbar_scrolling_view_behavior
,但随后 AppBar 覆盖了页面。我尝试将行为移动到片段中的根节点,我尝试了片段中不同节点上的 scrollFrags。我尝试用 CoordinatedLayout 包装片段。
FAB 也没有为 Snackbars 升级,这些都没有帮助。我只是想将 FAB 移动到活动视图,然后为所有内容隐藏它,并使用事件侦听器和我的 SharedViewModel 来点击它需要的一页,但后来我注意到 AppBar 滚动问题并且这不是那么简单使固定。我认为这都应该是基本的内置内容。我缺少什么容易的东西吗?我真的需要一些帮助,谢谢
好吧,我仍然喜欢答案。我是否应该为每个页面/片段设置一个 AppBar/Toolbar & CordinatorLayout?
我的解决方案只是一个解决方法:
共享视图模型
val onFabClick: MutableLiveData<(() -> Unit)?> = MutableLiveData(null)
片段
sharedViewModel.onFabClick.value = { this.localMethod() }
主要活动
override fun onCreate(savedInstanceState: Bundle?) {
val fab = binding.floatingActionButton
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.ListFragment -> {
fab.show()
updateAppBarScrollFlags(true)
}
else -> {
fab.hide()
updateAppBarScrollFlags(false)
}
}
}
fab.setOnClickListener {
//this enables the FAB to be clicked and trigger a method that can be assigned in any Fragment
sharedViewModel.onFabClick.value?.invoke()
}
}
private fun updateAppBarScrollFlags(isScrollEnabled: Boolean) {
val toolbar = binding.toolbar
val params = toolbar.layoutParams as AppBarLayout.LayoutParams
if (isScrollEnabled) {
params.scrollFlags = (AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
or AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS
or AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP)
} else {
params.scrollFlags = 0
}
toolbar.layoutParams = params
}