如何让ScrollView内Guideline使用视口百分比实现上滑覆盖布局效果
问题根因
你放在NestedScrollView内部的Guideline的百分比是基于其直接父布局(overlayInnerLayout)的高度计算的,你开启了android:fillViewport="true",当NestedScrollView的内容总高度超过本身可视高度时,overlayInnerLayout的高度就是内容总高度而非屏幕高度,所以70%的比例不符合预期。
方案1:最小改动适配现有布局
无需修改现有布局结构,仅需在代码中动态计算占位View的高度为屏幕可视高度的70%即可:
- 移除NestedScrollView内部的
verticalGuidelineOverlayGuideline - 在页面初始化时通过ViewTreeObserver监听ScrollView的渲染完成事件,动态设置spacerView的高度:
scrollView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { // 移除监听避免重复回调 scrollView.viewTreeObserver.removeOnGlobalLayoutListener(this) // 获取ScrollView的高度(即全屏可视高度) val scrollViewHeight = scrollView.height // 计算70%高度作为占位高度 val spacerHeight = (scrollViewHeight * 0.7).toInt() // 赋值给占位View val layoutParams = spacerView.layoutParams layoutParams.height = spacerHeight spacerView.layoutParams = layoutParams } })
Java版本代码参考:
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { scrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this); int scrollViewHeight = scrollView.getHeight(); int spacerHeight = (int) (scrollViewHeight * 0.7); ViewGroup.LayoutParams layoutParams = spacerView.getLayoutParams(); layoutParams.height = spacerHeight; spacerView.setLayoutParams(layoutParams); } });
方案2:用官方嵌套滑动组件实现更流畅效果
使用CoordinatorLayout+AppBarLayout的组合,系统自带滑动联动效果,无需处理滑动逻辑,过渡更流畅,核心布局如下:
<androidx.coordinatorlayout.widget.CoordinatorLayout android:id="@+id/parentLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 底层会被覆盖的70%区域内容 --> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/firstConstraintLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/red5F"> <!-- 此处放置你的底层内容 --> </androidx.constraintlayout.widget.ConstraintLayout> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/transparent" app:elevation="0dp"> <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <!-- 70%屏幕高度的透明占位View --> <View android:layout_width="match_parent" android:layout_height="0dp" android:id="@+id/transPlaceHolder" android:background="@android:color/transparent"/> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 此处放置你的可上滑展示内容 --> </LinearLayout> </androidx.core.widget.NestedScrollView> </androidx.coordinatorlayout>
同样在初始化时动态设置占位View的高度为屏幕高度的70%即可,无需额外处理滑动逻辑。
内容的提问来源于stack exchange,提问作者user1114
相关产品推荐
相关产品推荐

