用于滚动视图实现定头效果

用于支持定头的工具类

首先定义一个具体的接口,用于规范具体的操作,以方便扩展,具体代码如下:

package com.sun.view.vieweffect;

/**
 * 渐变效果
 * Created by sun on 2016/4/27.
 */
public interface GradientEffect {
    /**
     * 初始化数据
     */
    void onInitData();

    /**
     * 获取渐变吸收
     *
     * @return
     */
    void generateRatio();

    /**
     * 渐变回调监听
     *
     * @param l
     */
    void setOnGradientEffectListener(OnGradientEffectListener l);

    interface OnGradientEffectListener {
        /**
         * 渐变回调
         *
         * @param ratio 渐变系数(最小为0最大为1)
         */
        void onGrade(float ratio);
    }

    void stop();
}

这是具体的功能实现,需要扩展的同学可以参考扩展,具体代码如下:

package com.sun.view.vieweffect;

import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;

import com.sun.util.LogUtil;

/**
 * 可用于实现Title渐变效果或者吸顶效果
 * 

* 初始时,滑动视图必须在悬浮视图的下方 * Created by sun on 2016/4/27. */ public class GradientEffectImpl implements GradientEffect { private final String TAG = getClass().getSimpleName(); /*渐变效果监听器*/ private OnGradientEffectListener mOnGradientEffectListener; /*悬浮视图*/ private View hoverView; /*滑动视图*/ private View sliderView; /*悬浮视图初始Y坐标*/ private int initialHoverViewY = -1; /*滑动视图初始Y坐标*/ private int initialSliderViewY = -1; /*悬浮视图高度*/ private int hoverViewHeight = -1; /*滑动视图高度*/ private int sliderViewHeight = -1; /*初始差值,如果hoverView或sliderView高度改变,随之改变*/ private float initialDValue = -1; /*渐变系数*/ private float mRatio = -1; /*是否完成初始化*/ private boolean isInitial = false; private ViewTreeObserver.OnGlobalLayoutListener mHoverListener = new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { LogUtil.i(TAG, "----hoverView------onGlobalLayout----->--"); int tempHoverViewHeight = hoverView.getHeight(); if (tempHoverViewHeight == hoverViewHeight) return; if (tempHoverViewHeight > 0 && initialHoverViewY == -1) { initialHoverViewY = getScreenY(hoverView); } hoverViewHeight = tempHoverViewHeight; tryInitDValue(); } }; private ViewTreeObserver.OnGlobalLayoutListener mSliderListener = new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { LogUtil.i(TAG, "----sliderView------onGlobalLayout----->--"); int tempSliderViewHeight = sliderView.getHeight(); if (tempSliderViewHeight == sliderViewHeight) return; if (tempSliderViewHeight > 0 && initialSliderViewY == -1) { initialSliderViewY = getScreenY(sliderView); } sliderViewHeight = tempSliderViewHeight; tryInitDValue(); } }; private ViewTreeObserver.OnPreDrawListener mOnDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { LogUtil.i(TAG, "----sliderView------onPreDraw----->--"); generateRatio(); return true; } }; /** * 初始时,sliderView必须在hoverView的下方 * * @param hoverView 悬浮视图 * @param sliderView 滑动视图 */ public GradientEffectImpl(View hoverView, View sliderView) { this.hoverView = hoverView; this.sliderView = sliderView; } /** * 建议在滑动视图容器的onAttachedToWindow方法中调用,用于初始化数据 */ @Override public void onInitData() { if (isInitial) return; isInitial = true; hoverView.getViewTreeObserver().addOnGlobalLayoutListener(mHoverListener); sliderView.getViewTreeObserver().addOnGlobalLayoutListener(mSliderListener); sliderView.getViewTreeObserver().addOnPreDrawListener(mOnDrawListener); } @Override public void generateRatio() { LogUtil.i(TAG, "-----generateRatio----->----0-----"); float ratio; if (sliderView.isShown()) { float tempDValue = getCurrentDValue(); if (tempDValue < 0) {//滑动视图基线在悬浮视图的上方 ratio = 1; LogUtil.i(TAG, "-----generateRatio----->----1-----"); } else if (tempDValue > initialDValue) {//滑动视图基线在悬浮视图基线的下方,并且滑动视图越过原位置,继续被向下拉动 ratio = 0; LogUtil.i(TAG, "-----generateRatio----->----2-----"); } else {//滑动视图基线在悬浮视图基线的下方,并且被向上拉动 float offset = initialDValue - tempDValue; ratio = offset / initialDValue; LogUtil.i(TAG, "-----generateRatio----->----3-----"); } } else {//滑动视图被移除出当前window ratio = 1; LogUtil.i(TAG, "-----generateRatio----->----4-----"); } if (mOnGradientEffectListener != null && mRatio != ratio) { mRatio = ratio; mOnGradientEffectListener.onGrade(ratio); } } @Override public void setOnGradientEffectListener(OnGradientEffectListener l) { mOnGradientEffectListener = l; } /** * 尝试去计算初始差值 */ private void tryInitDValue() { if (hoverViewHeight == -1 || sliderViewHeight == -1 || initialHoverViewY == -1 || initialSliderViewY == -1) return; initialDValue = getDValue(hoverViewHeight, initialHoverViewY, sliderViewHeight, initialSliderViewY); } /** * 获取当前差值 * * @return 当前差值 */ private int getCurrentDValue() { int tempHoverViewY = getScreenY(hoverView); int tempSliderViewY = getScreenY(sliderView); return getDValue(hoverViewHeight, tempHoverViewY, sliderViewHeight, tempSliderViewY); } /** * 计算差值 * * @param hoverViewHeight 悬浮视图的高度 * @param hoverViewY 悬浮视图的y坐标 * @param sliderViewHeight 滑动视图的高度 * @param sliderViewY 滑动视图的y坐标 * @return 差值 */ private int getDValue(int hoverViewHeight, int hoverViewY, int sliderViewHeight, int sliderViewY) { int sliderViewBottom = sliderViewHeight + sliderViewY;//滑动视图当前基线 int hoverViewBottom = hoverViewHeight + hoverViewY;//悬浮视图当前基线 return sliderViewBottom - hoverViewBottom; } /** * 获取当前view在屏幕中的y坐标 * * @param view 当前视图 * @return y坐标 */ private int getScreenY(View view) { int[] location = new int[2]; view.getLocationOnScreen(location); return location[1]; } @Override public void stop(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { hoverView.getViewTreeObserver().removeOnGlobalLayoutListener(mHoverListener); sliderView.getViewTreeObserver().removeOnGlobalLayoutListener(mSliderListener); sliderView.getViewTreeObserver().removeOnPreDrawListener(mOnDrawListener); }else{ hoverView.getViewTreeObserver().removeGlobalOnLayoutListener(mHoverListener); hoverView.getViewTreeObserver().removeGlobalOnLayoutListener(mSliderListener); mOnDrawListener = null; } } }

具体的使用示例如下:

private void setNavGradient() {
        mGradientEffect = new GradientEffectImpl(vNavBar, mHeaderImage);
        mGradientEffect.setOnGradientEffectListener(new GradientEffect.OnGradientEffectListener() {
            @Override
            public void onGrade(float ratio) {
                //设置导航条背景透明度
                int alpha = (int) (ratio * 255);

                vNavBar.getBackground().setAlpha(alpha);
                vTipLine.getBackground().setAlpha(alpha);
                if (ratio > 0) {//导航条完全不透明
                    mHeaderBackBtn.setImageDrawable(getResources().getDrawable(R.drawable.top_btn_icon_back_selector));
                    mHeaderShareBtn.setImageDrawable(getResources().getDrawable(R.drawable.top_btn_icon_share_selector));
                    if (mO.equals("0")) {
                        mHeaderSortBtn.setImageResource(R.drawable.btn_time_down_selector);
                    } else {
                        mHeaderSortBtn.setImageResource(R.drawable.btn_time_up_selector);
                    }
                } else {
                    mHeaderBackBtn.setImageDrawable(getResources().getDrawable(R.drawable.top_btn_icon_back_white_selector));
                    mHeaderShareBtn.setImageDrawable(getResources().getDrawable(R.drawable.top_btn_icon_share_white_selector));
                    if (mO.equals("0")) {
                        mHeaderSortBtn.setImageResource(R.drawable.btn_time_down_white);
                    } else {
                        mHeaderSortBtn.setImageResource(R.drawable.btn_time_up_white);
                    }
                }
            }
        });
        mGradientEffect.onInitData();
    }

释放资源:

        if (mGradientEffect != null) {//释放渐变效果监听
            mGradientEffect.stop();
        }

你可能感兴趣的:(用于滚动视图实现定头效果)