先说冲突:ViewPager 里面嵌套 RecyclerView 再嵌套RecyclerView就会导致设置的layout_scrollFlags="scroll|enterAlways"失效。解决办法很简单,设置 子RecyclerView.setNestedScrollingEnabled = false
我们的需求是:最上面搜索栏固定,中间轮播图位置滑动隐藏,接下来是TabLayout滑动上去之后固定。
而且,TabLayout固定之后,子View优先滑动,未固定,父View优先滑动。
这个情况在ViewPager的多个Fragment交替滑动中会发现。
直接上xml代码。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
//顶部固定位置
<View
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginTop="45dp"
android:background="@color/blue" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
//隐藏部分
<RelativeLayout
android:id="@+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="13dp"
android:layout_marginBottom="10dp"
app:layout_scrollFlags="scroll|enterAlways">
<!-- scroll 往上滚 优先父 往下拉 先父后子-->
<!-- scroll|enterAlways 往上滚 优先父 往下拉 先子后父-->
</RelativeLayout>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:id="@+id/ll_tab"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
//需要注意 androidx 在String中的配置是: <string name="appbar_scrolling_view_behavior" translatable="false">com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior</string>
//滑动上去固定显示
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="58dp"
android:layout_marginLeft="18dp"
app:layout_collapseMode="pin" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_page"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
部分Java代码:默认设置Scroll模式不需要考虑这些。
//监听固定菜单栏的位置来改变AppBarLayout的ScrollFlags
appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//测量出llTab菜单栏的高度,因为verticalOffset不停在更新,只需要记录第一次的。
if (isFirst && llTab.getTop() != 0) {
layoutY = llTab.getTop();
isFirst = false;
}
if (verticalOffset == -layoutY) {
//菜单栏固定,子View滑动优先
setAppBarScroll(false);
} else {
//菜单栏不固定,父View滑动优先
setAppBarScroll(true);
}
}
});
//更改AppBarLayout的ScrollFlags
private void setAppBarScroll(boolean isDefault) {
View mAppBarChildAt = appBar.getChildAt(0);
AppBarLayout.LayoutParams mAppBarParams = (AppBarLayout.LayoutParams) mAppBarChildAt.getLayoutParams();
if (isDefault) {
//优先子view滑动
mAppBarParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
} else {
//优先父view滑动
mAppBarParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL);
}
mAppBarChildAt.setLayoutParams(mAppBarParams);
}
网友评论