UC浏览器主界面滑动折叠效果 使用自定义behavior实现 难度五颗星*****

本文详细介绍了如何使用自定义Behavior实现UC浏览器主界面的滑动折叠效果,包括RecyclerView的布局调整、头部视图的平移、缩放、渐变以及文本框的移动和背景色变化等关键步骤,涉及滚动处理和动画效果。
摘要由CSDN通过智能技术生成


思路:!!!!!!!!!!!

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值