思路:!!!!!!!!!!!
RcycleView上的HeadScrollBehavior 思路:
1。让recycleview居于头部的下方
---方案:
重写layoutDependsOn 让当前recycleview去依赖头部视图
重写onDependentViewChanged 获取到依赖的头部视图的高度,给recycleview设置setTranslationY
2.处理头部向上平移
在onNestedPreScroll 中 向上滑动是dy>0
float newTranslationY = dependency.getTranslationY() - dy;
//计算出最小平移的y距离
float minTranslationY = -(dependency.getHeight() - finalHeight);
if (newTranslationY > minTranslationY) {
dependency.setTranslationY(newTranslationY);
//在图片折叠的情况下,
// 1,不允许RecyclerView自身处理滚动
consumed[1] = dy;
// 2,只能和图片一起向上平移
}
3.recycleview往上平移
onDependentViewChanged中
//让RecyclerView在y方向上平移一段距离
child.setTranslationY(dependency.getHeight() + dependency.getTranslationY());
4.向下平移的处理
onNestedScroll方法中:
if (dyUnconsumed >= 0) {
return;
}
float newTranslationY = dependency.getTranslationY() - dyUnconsumed;
if (newTranslationY < 0) {
dependency.setTranslationY(newTranslationY);
}
5.处理图片的缩放和渐变
onDependentViewChanged 中:
//计算图片平移的百分比
float percent = Math.abs(dependency.getTranslationY() / (dependency.getHeight() - finalHeight));
// Log.i("test", "percent:" + percent);
//图片的缩放和透明度处理
dependency.setScaleX(1 + percent);
dependency.setScaleY(1 + percent);
dependency.setAlpha(1 - percent);
6.手指快速滑动图片的缓慢打开和关闭
onNestedPreFling--快速滑翔
判断速度,比如速度大于800 我们才认为是快速滑动了。
核心代码:
private boolean startExpandOrClose(float velocityY){
//获取松开手瞬间,图片已经平移的距离
float translationY = dependency.getTranslationY();
//图片向上移动的最终Y坐标位置-注意是负数
float upFinalTranslationY=-(dependency.getHeight()-finalHeight);
float downFinalTranslationY=0;
//定义boolean值确定是否是向闭合的状态滚动
boolean isClose=false;
if(Math.abs(velocityY)<=800){
//判断松开手时已经平移的位置和已经平移位置与向上平移位置的差值的绝对值进行比较
if(Math.abs(translationY) < Math.abs(translationY-upFinalTranslationY)){
isClose=false;
}else{
isClose=true;
}
}else{
//这里代表快速滑动
if(velocityY>0){
//从松开手的瞬间位置自动滚动到完全闭合的位置
isClose=true;
}else{
//从松开手的瞬间位置自动滚动到完全展开的位置
isClose=false;
}
}
//确定滚动的目标点
float targetTranslationY=isClose?upFinalTranslationY:downFinalTranslationY;
int startY= (int) translationY;
int dy= (int) (targetTranslationY-translationY);
mScroller.startScroll(0,startY,0,dy);
handler.post(flingRunnable);
isScrolling=true;
return true;
}
private Handler handler=new Handler();
private Runnable flingRunnable=new Runnable() {
@Override
public void run() {
//Scroller滚动的原理:
//是一帧一帧向前滚动的,滚动的过程中,要不断的计算是否滚动到目标,如果未滚动到,则继续滚动
//判断Scroller是否已经滚动到目标位置
//这个方法还可以判断是否有下一个新的小目标点
if(mScroller.computeScrollOffset()){
//getCurrY:指获取下一个新的位置
dependency.setTranslationY(mScroller.getCurrY());
handler.post(this);
}else{
isScrolling=false;
}
}
};
7.文本框的移动和背景色变化-HeadTextBeahvior
public class HeadTextBehavior extends CoordinatorLayout.Behavior<View> {
private final ArgbEvaluator argbEvaluator;
public HeadTextBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
argbEvaluator = new ArgbEvaluator();
initOffset = context.getResources().getDimension(R.dimen.initOffset);
collapsedOffset = context.getResources().getDimension(R.dimen.collapsedOffset);
finalHeight = (int) context.getResources().getDimension(R.dimen.finalHeight);
initMargin = (int) context.getResources().getDimension(R.dimen.initMargin);
finalMargin = (int) context.getResources().getDimension(R.dimen.finalMargin);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
if (dependency.getId() == R.id.iv_head) {
return true;
}
return super.layoutDependsOn(parent, child, dependency);
}
private float initOffset = 130;
private float collapsedOffset = 5;
private int finalHeight = 50;
private int initMargin=20;
private int finalMargin=5;
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
//处理随着图片向上移动,当前控件也向上移动
float percent = Math.abs(dependency.getTranslationY() / (dependency.getHeight() - finalHeight));
// Log.i("test","percent:"+percent);
float translationY = collapsedOffset + (initOffset - collapsedOffset) * (1-percent);
child.setTranslationY(translationY);
int color= (int) argbEvaluator.evaluate(percent, Color.RED,Color.GREEN);
child.setBackgroundColor(color);
int margin= (int) (finalMargin+(initMargin-finalMargin)*(1-percent));
CoordinatorLayout.LayoutParams params= (CoordinatorLayout.LayoutParams) child.getLayoutParams();
params.setMargins(margin,0,margin,0);
child.setLayoutParams(params);
return true;
}
}
UC案例思路:
findFirstDependency:决定了你的头部视图是谁!
默认的是:
@Override
View findFirstDependency(List<View> views) {
for (int i = 0, z = views.size(); i < z; i++) {
View view = views.get(i);
if (view instanceof AppBarLayout) {
return view;
}
}
return null;
}
getScrollRange(View v):决定你的头部视图滚动的范围 !
决定了我们必须要去继承 HeaderScrollingViewBehavior 但是由于这个类是包级的 所以需要去拷贝源代码
----------------------------------------------------------------------------------------
代码实现 布局文件 :-----
activity_main
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout android:id="@+id/activity_main" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout app:layout_behavior="@string/NewsPagerBehavior" android:id="@+id/fl_head" android:background="@android:color/holo_blue_light" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/tv_head" android:gravity="center_vertical" android:text="NewsPaget" android:layout_width="wrap_content" android:layout_height="250dp" android:textColor="#333" android:padding="12dp" android:layout_gravity="center" /> </FrameLayout> <FrameLayout app:layout_behavior="@string/TitleBehavior" android:background="#486ef9" android:layout_width="match_parent" android:layout_height="45dp"> <TextView android:id="@+id/tv_title" android:text="uc 头条" android:paddingRight="12dp" android:paddingLeft="12dp" android:textColor="#fff" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </FrameLayout> <android.support.design.widget.TabLayout app:layout_behavior="@string/tabBehavior" android:id="@+id/tab_layout" android:background="@color/colorPrimary" app:tabIndicatorColor="#a3a1ff" app:tabTextColor="#bbffffff" app:tabSelectedTextColor="#c9c9c9" app:tabGravity="fill" android:layout_width="match_parent" android:layout_height="45dp"/> <android.support.v4.view.ViewPager app:layout_behavior="@string/ContentBehavior" android:id="@+id/vp" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#f5ffffff"/> </android.support.design.widget.CoordinatorLayout>----------------
2!!!!!!!!:fragment.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout android:id="@+id/activity_main" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout app:layout_behavior="@string/NewsPagerBehavior" android:id="@+id/fl_head" android:background="@android:color/holo_blue_light" android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/tv_head" android:gravity="center_vertical" android:text="NewsPaget" android:layout_width="wrap_content" android:layout_height="250dp" android:textColor="#333" android