头部视差效果
-
1.案例演示:
2.实现逻辑:
- 1.在ListView中添加头部后,再调用overScrollBy方法(),在里面滑动的时候不断增加ImageView高度直到达到最高高度停止;
==overScrollBy方法()这个方法先不简介,往后看!==
//不断增加ImageView高度
int mHeaderHeight=mImageViewHeader.getHeight()-deltaY/3;
- 2.最大高度的计算为:当前图片的高度和ImageView的高度进行对比,如果图片的高度大于ImageView的高度则最大高度为图片自身高度,否则为ImageView高度的2倍;
//获取图片高度:
int pictureHeight=mImageViewHeader.getDrawable().getIntrinsicHeight();
//获取控件高度:
//在onLayout执行完毕后调用该方法,可以准确获取到控件高度:
mImageViewHeader.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mImageViewHeader.getViewTreeObserver().removeOnGlobalLayoutListener(this);
mOrignalHeight=mImageViewHeader.getHeight();
//设置最大高度:
int MaxHeight=mOrignalHeight>pictureHeight ? mOrignalHeight*2 : pictureHeight;
}
});
- 3.下拉改变图片的高度:介绍下onScrollOverBy()
/**
* 在listview滑动到头的时候执行,可以获取到继续滑动的距离和方向
* deltaX:继续滑动x方向的距离
* deltaY:继续滑动y方向的距离 负:表示顶部到头 正:表示底部到头
* maxOverScrollX:x方向最大可以滚动的距离
* maxOverScrollY:y方向最大可以滚动的距离
* isTouchEvent: true: 是手指拖动滑动 false:表示fling靠惯性滑动;
*/
//上面提到已经在onScrollOverBy()里面获取到了下拉时控件的高度和最大高度
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (deltaY<0 && isTouchEvent){//deltaY<0是下拉,isTouchEvent=true表明是手指下拉
if (mImageViewHeader!=null){
mHeaderHeight=mImageViewHeader.getHeight()-deltaY/3;
if (mHeaderHeight>MaxHeight) mHeaderHeight=MaxHeight;
//下拉后更新图片高度:
mImageViewHeader.getLayoutParams().height=mHeaderHeight;
mImageViewHeader.requestLayout();//更新
}
}
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
- 4.松手后还原图片高度:主要是通过ValueAnimator属性动画将图片高度还原;
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction()==MotionEvent.ACTION_UP){//松手
//松手后缓慢让图片还原自身高度:
ValueAnimator valueAnimator=ValueAnimator.ofInt(mImageViewHeader.getHeight(),mOrignalHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int height= (int) animation.getAnimatedValue();
mImageViewHeader.getLayoutParams().height=height;
mImageViewHeader.requestLayout();//更新
}
});
valueAnimator.setDuration(350);
//增加滑动到头的弹性收缩特效
valueAnimator.setInterpolator(new OvershootInterpolator(5));
valueAnimator.start();
}
return super.onTouchEvent(ev);
}
- 5.细节处理:例如取消ListView滑动到头的蓝色阴影、增加滑动到头的弹性收缩特效等;
listview.setOverScrollMode(ListView.OVER_SCROLL_NERVER);
- 3.GitHub项目源码:戳我