上一篇文章实现了RecyclerView的粘性头部 ,这次来介绍下ScrollView如何实现粘性头部,其实实现思路几乎一样!
效果图 上一篇文章类似效果
实现思路 1.布局结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout android:id ="@+id/appbar" android:layout_width ="match_parent" android:layout_height ="wrap_content" > <android.support.v7.widget.Toolbar android:layout_width ="match_parent" android:layout_height ="wrap_content" android:theme ="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:navigationIcon ="?attr/homeAsUpIndicator" app:title ="title" /> </android.support.design.widget.AppBarLayout > <android.support.v4.widget.NestedScrollView android:id ="@+id/rv_scrollview" android:layout_width ="match_parent" android:layout_height ="match_parent" app:layout_behavior ="@string/appbar_scrolling_view_behavior" > <include layout ="@layout/scroll_content" /> </android.support.v4.widget.NestedScrollView > <TextView android:id ="@+id/sticky_header" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:padding ="20dp" android:background ="#e89112" android:gravity ="center" android:text ="sticky header" android:textColor ="@android:color/white" /> </android.support.design.widget.CoordinatorLayout >
scroll_content
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android" android:layout_width ="match_parent" android:layout_height ="match_parent" android:orientation ="vertical" android:background ="#f2f2f2" > <ImageView android:layout_width ="match_parent" android:layout_height ="200dp" android:src ="@mipmap/girl" android:scaleType ="centerCrop" /> <TextView android:layout_width ="match_parent" android:layout_height ="wrap_content" android:padding ="20dp" /> <TextView android:layout_marginBottom ="1dp" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="A" android:padding ="20dp" android:background ="@android:color/white" /> <TextView android:layout_marginBottom ="1dp" android:layout_width ="match_parent" android:layout_height ="wrap_content" android:text ="B" android:padding ="20dp" android:background ="@android:color/white" /> ...... </LinearLayout >
ps:NestedScrollView中包括三部分,普通header、sticky header、item;其中sticky header是假view,只是为了占个高度。真正的sticky header在CoordinatorLayout中。
2.滑动处理 主要就是添加滑动监听,把NestedScrollView的滑动距离算出来(与RecyclerView的区别就是不需要累加,scrollY就是滑动的总距离),然后与最大滑动距离比较,即普通header的高度,如果差值>0,则滑动此距离,<0就不滑动。这样就可以把某个header定在一处。
主要代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 maxDist=ScreenUtils.dip2px(this ,200 ); stickyView=findViewById(R.id.sticky_header); scrollView= (NestedScrollView) findViewById(R.id.rv_scrollview); appbar= (AppBarLayout) findViewById(R.id.appbar); appbar.post(new Runnable() { @Override public void run () { barHeight= appbar.getMeasuredHeight(); stickyView.setTranslationY(maxDist+barHeight); } }); scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { @Override public void onScrollChange (NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { Log.e(TAG,"scrollY:" +scrollY); int tranY=Math.max(0 ,maxDist-scrollY); stickyView.setTranslationY(tranY+barHeight); } });