一、概述
之前一直在专注CSDN博客上,也从中学到了很多知识,不过最近各种原因,加上换了新公司,新的项目时间比较急,导致博客始终没有更新了,借着这个机会转向更方便的简书,今后可能就一直在简书上更新自己的所得了,以上纯属扯淡,为自己的懒惰找借口。。。回到正题,最近公司的项目真的很忙,主要安卓端较IOS停止了一年的时间,我拿到的还是去年3月份的代码,IOS端一直在完善,最悲催的是我们要同时上线。。。所以时间紧张程度可想而知,女朋友都说我累得像条狗。。。。又扯了一波,最近项目上用到一个下拉放大背景图片的动画过程,对,就是苹果界面的效果,悲催的用安卓写出苹果的App
二、设计思路
最初的想法是简单的手势检测,然后layout改变View的布局位置,实现view的放大缩小,这样虽然可以实现但滑动的流畅度大大下降,缺乏苹果界面的效果,于是想到滚动的scrollingView,这里就是自定义的ScrollingView,代码也比较简单
三、代码实现
由于代码比较简单,我这里 就只分析核心的部分代码
获取缩放的View:
/**
* 获取缩放的view
*/
@Override
protected voidonFinishInflate() {
super.onFinishInflate();
setOverScrollMode(OVER_SCROLL_NEVER);
if(headView==null&& getChildAt(0) !=null&& getChildAt(0)instanceofViewGroup) {
ViewGroup viewGroup = (ViewGroup) getChildAt(0);
if(viewGroup.getChildCount() >0) {
//默认获取第一个View为缩放的headView
headView= getChildAt(0);
}
从代码中可以看出,这里默认设置第一个view为缩放的对象,当然也可以设置指定的Veiw
/**
* 设置要缩放的view
*
*@paramheadView
*/
public voidsetHeadView(View headView) {
this.headView= headView;
}
手势检测:
照例先看代码
switch(ev.getAction()) {
caseMotionEvent.ACTION_DOWN:
break;
caseMotionEvent.ACTION_MOVE:
if(!isTrants) {
if(getScrollY() ==0) {
y= ev.getY();
}
}
intdistance = (int) (ev.getY() -y);
if(distance <0)
break;
isTrants=true;
setHeadViewScroll(distance);
return true;
caseMotionEvent.ACTION_UP:
isTrants=false;
springback();
break;
}
return super.onTouchEvent(ev);
这里就是要检测手势的滑动,当像上滑动时不执行缩放,当开始向下滑动式记录当时的位置,并执行缩放。
执行缩放:
缩放的代码就是给布局的宽和高增加距离,位移和缩放基本都是啥通过如此的方法完成位移和缩放
ViewGroup.LayoutParams params =headView.getLayoutParams();
params.width= (int) (viewWidth+ distance);
params.height= (int) (viewWidth* (viewWidth+ distance /viewWidth*1.0));
((MarginLayoutParams) params).setMargins(-(params.width-viewWidth) /2,0,-(params.width-viewWidth) /2,0);
headView.setLayoutParams(params);
这里面有两点要注意的地方:
1.缩放的长度和宽度要成比例缩放
2.缩放完成后的布局要加上居中,否则你的布局会从一个角缩放,很不协调
松手回弹 :
这个过程就是一个属性动画,在手松开的时候自动执行动画,
intdiatance =headView.getMeasuredWidth() -viewWidth;
ValueAnimator valueAnimator = ObjectAnimator.ofFloat(diatance,0.0f).setDuration((long) (diatance *springRate));
valueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator animation) {
setHeadViewScroll((Float) animation.getAnimatedValue());
}
});
valueAnimator.start();
到此,整个VIew的功能就实现了 ,不过还有一些可以优化的地方,比如设置滑动位置和速率等,另外,及时滑动监听,因为有时在滑动的同时会执行其他的动画,比如我的项目中的这个VIew,下一章准备详细ji介绍这个View,具体监听的方法就是重写onScroChangae()
@Override
protected voidonScrollChanged(intl, intt, intoldl, intoldt) {
super.onScrollChanged(l,t,oldl,oldt);
if(onScrollListener!=null)onScrollListener.onScroll(l,t,oldl,oldt);
privateOnScrollListeneronScrollListener;
public voidsetOnScrollListener(OnScrollListener onScrollListener) {
this.onScrollListener= onScrollListener;
public interfaceOnScrollListener {
voidonScroll(intscrollX, intscrollY, intoldScrollX, intoldScrollY);
}
搞定,以上作为一点心得与大家分享,有不足之处还请指正,共同进步。。。