一、效果图

仿开眼首页 - 图1
iShot2020-08-1823.43.52.gif

二、实现

关键 behaviro:

  1. **
  2. *
  3. * 自定义Behavior :实现RecyclerView(或者其他可滑动View,如:NestedScrollView) 滑动覆盖header 的效果
  4. * Created by zhouwei on 16/12/19.
  5. */
  6. public class CoverHeaderScrollBehavior extends CoordinatorLayout.Behavior<View> {
  7. public static final String TAG = "CoverHeaderScroll";
  8. public CoverHeaderScrollBehavior(Context context, AttributeSet attributeSet){
  9. super(context,attributeSet);
  10. }
  11. @Override
  12. public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
  13. Log.i(TAG,"onLayoutChild.....");
  14. CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
  15. if(params!=null && params.height == CoordinatorLayout.LayoutParams.MATCH_PARENT){
  16. child.layout(0,0,parent.getWidth(),parent.getHeight());
  17. child.setTranslationY(getHeaderHeight());
  18. return true;
  19. }
  20. return super.onLayoutChild(parent, child, layoutDirection);
  21. }
  22. @Override
  23. public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
  24. return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
  25. }
  26. @Override
  27. public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
  28. super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
  29. // 在这个方法里面只处理向上滑动
  30. if(dy < 0){
  31. return;
  32. }
  33. float transY = child.getTranslationY() - dy;
  34. Log.i(TAG,"transY:"+transY+"++++child.getTranslationY():"+child.getTranslationY()+"---->dy:"+dy);
  35. if(transY > 0){
  36. child.setTranslationY(transY);
  37. consumed[1]= dy;
  38. }
  39. }
  40. @Override
  41. public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
  42. super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
  43. // 在这个方法里只处理向下滑动
  44. if(dyUnconsumed >0){
  45. return;
  46. }
  47. float transY = child.getTranslationY() - dyUnconsumed;
  48. Log.i(TAG,"------>transY:"+transY+"****** child.getTranslationY():"+child.getTranslationY()+"--->dyUnconsumed"+dxUnconsumed);
  49. if(transY > 0 && transY < getHeaderHeight()){
  50. child.setTranslationY(transY);
  51. }
  52. }
  53. /**
  54. * 获取Header 高度
  55. * @return
  56. */
  57. public int getHeaderHeight(){
  58. return Objects.requireNonNull(App.Companion.getMContext()).getResources().getDimensionPixelOffset(R.dimen.m160);
  59. }
  60. }

布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. xmlns:app="http://schemas.android.com/apk/res-auto">
  6. <ImageView
  7. android:layout_width="match_parent"
  8. android:layout_height="@dimen/m160"
  9. android:scaleType="centerCrop"
  10. android:src="@mipmap/wuhuang"
  11. />
  12. <androidx.core.widget.NestedScrollView
  13. android:layout_width="match_parent"
  14. android:layout_height="match_parent"
  15. android:background="@color/white"
  16. app:layout_behavior=".design.behavior.scroll.CoverHeaderScrollBehavior"
  17. >
  18. <TextView
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_margin="@dimen/m12"
  22. android:text="@string/large_text" />
  23. </androidx.core.widget.NestedScrollView>
  24. </androidx.coordinatorlayout.widget.CoordinatorLayout>

三、地址和参考

demo
Material Design 之 Behavior的使用和自定义Behavior