卜娃娃|Behavior实战,这交互炸了系列:仿小米音乐歌手详情页,自定义( 二 )
publicbooleanonStartNestedScroll(@NonNullCoordinatorLayoutcoordinatorLayout,@NonNullViewchild,@NonNullViewdirectTargetChild,@NonNullViewtarget,intaxes,inttype){//只接受内容View的垂直滑动returndirectTargetChild.getId()==R.id.ll_content&&axes==ViewCompat.SCROLL_AXIS_VERTICAL;}onNestedPreScroll()接下来就是处理滑动 , 上面效果分析提过:
Content部分的:
上滑范围=[topBarHeight,contentTransY]、下滑范围=[contentTransY,downEndY]即滑动范围为[topBarHeight,downEndY];
ElemeNestedScrollLayout要控制Content部分的TransitionY值要在范围内 , 具体处理如下:
Content部分里可滑动View往上滑动时:
如果Content部分当前TransitionY+View滑动的dy>topBarHegiht , 设置Content部分的TransitionY为Content部分当前TransitionY+View滑动的dy达到移动的效果来消费View的dy 。 如果Content部分当前TransitionY+View滑动的dy=topBarHegiht , 同上操作 。 如果Content部分当前TransitionY+View滑动的dy<topBarHegiht , 只消费部分dy(即Content部分当前TransitionY到topBarHeight差值) , 剩余的dy让View滑动消费 。Content部分里可滑动View往下滑动并且View已经不能往下滑动(比如RecyclerView已经到顶部还往下滑)时:
如果Content部分当前TransitionY+View滑动的dy>=topBarHeight并且Content部分当前TransitionY+View滑动的dy<=downEndY , 设置Content部分的TransitionY为Content部分当前TransitionY+View滑动的dy达到移动的效果来消费View的dyContent部分当前TransitionY+View滑动的dy>downEndY,只消费部分dy(即Content部分当前TransitionY到downEndY差值)并停止NestedScrollingChild2的View滚动 。 publicvoidonNestedPreScroll(@NonNullCoordinatorLayoutcoordinatorLayout,@NonNullViewchild,@NonNullViewtarget,intdx,intdy,@NonNullint[]consumed,inttype){floattransY=child.getTranslationY()-dy;//处理上滑if(dy>0){if(transY>=topBarHeight){translationByConsume(child,transY,consumed,dy);}else{translationByConsume(child,topBarHeight,consumed,(child.getTranslationY()-topBarHeight));}}if(dy<0&&!target.canScrollVertically(-1)){//处理下滑if(transY>=topBarHeight&&transY<=downEndY){translationByConsume(child,transY,consumed,dy);}else{translationByConsume(child,downEndY,consumed,(downEndY-child.getTranslationY()));stopViewScroll(target);}}}privatevoidstopViewScroll(Viewtarget){if(targetinstanceofRecyclerView){((RecyclerView)target).stopScroll();}if(targetinstanceofNestedScrollView){try{ClassextendsNestedScrollView>clazz=((NestedScrollView)target).getClass();FieldmScroller=clazz.getDeclaredField("mScroller");mScroller.setAccessible(true);OverScrolleroverScroller=(OverScroller)mScroller.get(target);overScroller.abortAnimation();}catch(NoSuchFieldException|IllegalAccessExceptione){e.printStackTrace();}}}privatevoidtranslationByConsume(Viewview,floattranslationY,int[]consumed,floatconsumedDy){consumed[1]=(int)consumedDy;view.setTranslationY(translationY);}onStopNestedScroll()在下滑Content部分从初始状态转换到展开状态的过程中松手就会执行收起的动画 , 这逻辑在onStopNestedScroll()实现 , 但注意如果动画未执行完毕手指再落下滑动时 , 应该在onNestedScrollAccepted()取消当前执行中的动画 。