我有一个包含 2 个或更多查看者的回收者视图,
CalendarView
- 全部在一个 viewhodler 中。问题是 CalendarView 的高度相当大,当 CalendarView 稍微离开屏幕并且我折叠/消失日历时,它会折叠但仍然占用空间,就像下面的屏幕截图一样。但奇怪的是,它只发生在
Android 8 & 9
。
初始屏幕截图:
问题截图(折叠简历后):
Viewholder Item 的 ClickListener:
val clickListener = View.OnClickListener {
// irrelevant code //
for (type in AllOptionsEnum.values()) {
// Expand Selected and Collapse Others
val detailView = this.root.findViewById<ViewGroup>(type.detailViewGroupId)
val labelView = this.root.findViewById<TextView>(type.labelViewId)
val checkBox = this.root.findViewById<CheckBox>(type.checkBoxId)
if (detailView.visibility == View.VISIBLE) {
// hide detailed view
detailView.setVisible(show = false)
checkBox.isChecked = false
} else {
// show
detailView.setVisible(show = (type.labelViewGroupId == it.id))
checkBox.isChecked = show = (type.labelViewGroupId == it.id)
}
// irrelevant code //
}
}
编辑1: 扩展功能:
fun View.setVisible(show: Boolean = true, invisible: Boolean = false) {
if (show) this.visibility = View.VISIBLE
else this.visibility = if (invisible) View.INVISIBLE else View.GONE
}
编辑2:
我尝试了另一种解决方案,即完全删除recyclerview并使用nestedscrollview重新构造整个屏幕,但它也有相同的效果。
编辑3:
我也尝试过下面的代码,但结果相同
// show detailView
if(type==Enums.StayWithUsWidgetType.TYPE_CALENDAR){
// show detailview and children
this.calendarDetailView.children.forEach {
it.visible()
}
}
// Hide detailView and children
if(type==Enums.StayWithUsWidgetType.TYPE_CALENDAR){
// hide all
this.calendarDetailView.children.forEach {
it.gone()
}
}
我不确定 Android Pie (2018) 如何处理布局中的可见性更改,特别是具有复杂布局层次结构的 CalendarView。
但请注意,“Android Pvisibilityawareimagebutton.setVisibility 只能从同一个库组调用”很明确:
最佳实践:
android:visibility="Gone"
使用可见性消失意味着您的视图不会占用布局上的任何空间,而“不可见”将占用布局上不必要的空间
因此请仔细检查您的
detailView.setVisible()
函数。理想情况下,它应该看起来像:
fun View.setVisible(show: Boolean) {
this.visibility = if (show) View.VISIBLE else View.GONE
}
所以,当你看到
setVisible(show = false)
时,就相当于在该视图上设置了visibility = View.GONE
。然而,这是一个假设,因为您的问题中没有提供此方法的实现。
一个可能的替代测试解决方案是将
CalendarView
包装在另一个布局中,例如 LinearLayout
或 FrameLayout
,然后设置此包装器布局的可见性,而不是 CalendarView
本身。例如:
<LinearLayout
android:id="@+id/calendarViewContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CalendarView
android:id="@+id/calendarView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
在点击侦听器中,您现在可以切换
calendarViewContainer
而不是 calendarView
的可见性:
val detailView = this.root.findViewById<ViewGroup>(if (type == AllOptionsEnum.CALENDAR) R.id.calendarViewContainer else type.detailViewGroupId)
如果问题仍然存在,另一种解决方法是在将可见性更改为
requestLayout()
后使用 GONE
方法。这将告诉 Android 系统再次测量和布局视图层次结构,这可能会解决您的问题。
detailView.setVisible(show = false)
detailView.requestLayout()
这不是最有效的方法,因为它可能会导致不必要的布局传递,但可能有必要在 Android Pie (9) 上解决这个特定问题。
关于编辑3:
// hide detailView if(type==Enums.StayWithUsWidgetType.TYPE_CALENDAR){ // hide detailview and children this.calendarDetailView.children.forEach { it.visible() } } // Hide detailView and children if(type==Enums.StayWithUsWidgetType.TYPE_CALENDAR){ // hide all this.calendarDetailView.children.forEach { it.gone() } }
我看到您试图单独隐藏
calendarDetailView
的每个子项(我认为是包含您的 ViewGroup
的 CalendarView
)。但是,目前还不清楚您是否将 calendarDetailView
本身的可见性设置为 GONE
。
我更愿意看到这段代码,其中
calendarDetailView
本身也设置为 GONE
:
if(type == Enums.StayWithUsWidgetType.TYPE_CALENDAR){
// hide all children
this.calendarDetailView.children.forEach {
it.visibility = View.GONE
}
// then hide the parent itself
this.calendarDetailView.visibility = View.GONE
}
您可以尝试以编程方式设置 Calenderview 高度,如下所示,这可以帮助您显示该视图的额外空间。
if(type==Enums.StayWithUsWidgetType.TYPE_CALENDAR){
// setup height when needed
this.calendarDetailView.children.forEach {
calendarDetailView.setLayoutParams(new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
}
}