Android ListView实现下拉顶部图片变大效果
本文实例为大家分享了AndroidListView下拉顶部图片变大的具体代码,供大家参考,具体内容如下
在git上查看牛人的代码,发现是反编译别人的代码,还没加注释,代码也没有完全编译完整,所以这里我做的简单的注释,仅供学习。
变量说明
这里变量包含了:自定义返回动画加速度、自定义动画线程、头部图片view,最后的y坐标,做好的比例,做大的比例等。
privatestaticfinalStringTAG="PullToZoomListView";
privatestaticfinalintINVALID_VALUE=-1;//重置值
//自定义加速度动画
privatestaticfinalInterpolatorsInterpolator=newInterpolator(){
publicfloatgetInterpolation(floatinterpolator){
floatf=interpolator-1.0F;
return1.0F+f*(f*(f*(f*f)));
}
};
privateintmActivePointerId=INVALID_VALUE;//当前手指的Id
privateFrameLayoutmHeaderContainer;//头部
privateintmHeaderHeight;//头部图片的高度
privateImageViewmHeaderImage;//头部图片
floatmLastMotionY=INVALID_VALUE;//最后y坐标
floatmLastScale=INVALID_VALUE;//最后的比例
floatmMaxScale=INVALID_VALUE;//最大的比例
privateOnScrollListenermOnScrollListener;//滑动监听
privateScalingRunnalablemScalingRunnalable;//动画线程
privateintmScreenHeight;//屏幕高度
privateImageViewmShadow;//阴影遮罩
自定义View初始化:设置了头部的头部和遮罩并且设置了监听。
/**
*初始化
*@paramparamContext
*/
privatevoidinit(ContextparamContext){
DisplayMetricsmetrics=newDisplayMetrics();
((Activity)paramContext).getWindowManager().getDefaultDisplay().getMetrics(metrics);
this.mScreenHeight=metrics.heightPixels;//屏幕高度赋值
this.mHeaderContainer=newFrameLayout(paramContext);//头部
this.mHeaderImage=newImageView(paramContext);//头部图片
intscreenWidth=metrics.widthPixels;//屏幕宽度
//设置头部View的样式设置屏幕宽度,最大样式高度为屏幕高度的9/16
setHeaderViewSize(screenWidth,(int)(9.0F*(screenWidth/16.0F)));
this.mShadow=newImageView(paramContext);//遮罩
FrameLayout.LayoutParamslayoutParams=
newFrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.gravity=Gravity.CENTER;
this.mShadow.setLayoutParams(layoutParams);//设置遮罩样式
//头部添加View
this.mHeaderContainer.addView(this.mHeaderImage);
this.mHeaderContainer.addView(this.mShadow);
//添加头部
addHeaderView(this.mHeaderContainer);
//初始化返回动画
this.mScalingRunnalable=newScalingRunnalable();
//设置监听
super.setOnScrollListener(this);
}
开启动画:判断当前的头部布局底部的位置–是否大于图片的初始化高度。
/**
*开启动画
*/
privatevoidendScraling(){
if(this.mHeaderContainer.getBottom()>=this.mHeaderHeight){
Log.d(TAG,"this.mScalingRunnalable.startAnimation(200L)");
this.mScalingRunnalable.startAnimation(200L);
}
}
多指触碰时将第0个手指赋值。
/**
*多点触碰的时候按下,当第0个有手指抬起,再次有手指按下后,将按下的事件的手指指针作为当前手指指针
*
*@parammotionEvent
*/
privatevoidonSecondaryPointerUp(MotionEventmotionEvent){
Log.d(TAG,"onSecondaryPointerUpmotionEvent.getPointerId(0)="+motionEvent.getPointerId(0));
Log.d(TAG,"onSecondaryPointerUpthis.mActivePointerId="+this.mActivePointerId);
if(motionEvent.getPointerId(0)==this.mActivePointerId){
this.mLastMotionY=motionEvent.getY(0);
this.mActivePointerId=motionEvent.getPointerId(0);
}
Log.d(TAG,"onSecondaryPointerUpmLastMotionY="+mLastMotionY);
Log.d(TAG,"onSecondaryPointerUpmActivePointerId="+mActivePointerId);
}
重置所有的数据
/**
*重置所有数据
*/
privatevoidreset(){
this.mActivePointerId=INVALID_VALUE;
this.mLastMotionY=INVALID_VALUE;
this.mMaxScale=INVALID_VALUE;
this.mLastScale=INVALID_VALUE;
}
向上滚动时修改布局样式
@Override
publicvoidonScroll(AbsListViewview,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount){
Log.d(TAG,"onScroll");
floatbottomSpacing=this.mHeaderHeight-this.mHeaderContainer.getBottom();
Log.d(TAG,"onScrollbottomSpacing="+bottomSpacing);
if((bottomSpacing>0.0F)&&(bottomSpacing
不同事件处理,修改布局样式
@Override
publicbooleanonTouchEvent(MotionEventmotionEvent){
switch(motionEvent.getAction()&MotionEvent.ACTION_MASK){
caseMotionEvent.ACTION_OUTSIDE:
caseMotionEvent.ACTION_DOWN:
if(!this.mScalingRunnalable.mIsFinished){
this.mScalingRunnalable.abortAnimation();
}
this.mLastMotionY=motionEvent.getY();
//获取第一个手指指针的ID
this.mActivePointerId=motionEvent.getPointerId(0);
this.mMaxScale=(this.mScreenHeight/this.mHeaderHeight);
this.mLastScale=(this.mHeaderContainer.getBottom()/this.mHeaderHeight);
Log.d(TAG,"onTouchEventACTION_DOWNmLastMotionY="+mLastMotionY);
Log.d(TAG,"onTouchEventACTION_DOWNmActivePointerId="+mActivePointerId);
Log.d(TAG,"onTouchEventACTION_DOWNmMaxScale="+mMaxScale);
Log.d(TAG,"onTouchEventACTION_DOWNmLastScale="+mLastScale);
break;
caseMotionEvent.ACTION_MOVE:
Log.d(TAG,"onTouchEventACTION_MOVEmActivePointerId"+mActivePointerId);
//获取当前id的手机指针
intpointer=motionEvent.findPointerIndex(this.mActivePointerId);
//判断指针不为空
if(pointer==INVALID_VALUE){
Log.e(TAG,"InvalidpointerId="+this.mActivePointerId+"inonTouchEvent");
}else{
//如果开始没有赋值,则需要赋值
if(this.mLastMotionY==INVALID_VALUE){
this.mLastMotionY=motionEvent.getY(pointer);
}
if(this.mHeaderContainer.getBottom()>=this.mHeaderHeight){
//获取头部样式
ViewGroup.LayoutParamsheaderParams=this.mHeaderContainer.getLayoutParams();
floatcurrentScale=((motionEvent.getY(pointer)-this.mLastMotionY+this.mHeaderContainer.getBottom())
/this.mHeaderHeight-this.mLastScale)
/2.0F+this.mLastScale;
if((this.mLastScale<=1.0D)&&(currentScale
向上返回时的动画
/**
*向上返回的动画
*/
classScalingRunnalableimplementsRunnable{
longmDuration;//持续时间
booleanmIsFinished=true;//是否结束
floatmScale;//比例
longmStartTime;//开始时间
ScalingRunnalable(){
}
/**
*中止动画
*/
publicvoidabortAnimation(){
this.mIsFinished=true;
}
/**
*是否中止
*
*@return
*/
publicbooleanisFinished(){
returnthis.mIsFinished;
}
publicvoidrun(){
Log.d(TAG,"ScalingRunnalablemIsFinished="+this.mIsFinished+"this.mScale="+this.mScale);
floatcurrentScale;
ViewGroup.LayoutParamsmHeaderContainerParams;//头部样式
//判断是否中止和已经滑动超过的默认大小
if((!this.mIsFinished)&&(this.mScale>1.0D)){
floatcurrentTime=((float)SystemClock.currentThreadTimeMillis()-(float)this.mStartTime)/(float)this.mDuration;
currentScale=this.mScale-(this.mScale-1.0F)*PullToZoomListView.sInterpolator.getInterpolation(currentTime);
Log.d(TAG,"ScalingRunnalablecurrentTime="+currentTime+"currentScale="+currentScale);
mHeaderContainerParams=PullToZoomListView.this.mHeaderContainer.getLayoutParams();
if(currentScale>1.0F){
Log.d(TAG,"ScalingRunnalablecurrentScale>1.0--修改头部高度");
mHeaderContainerParams.height=PullToZoomListView.this.mHeaderHeight;
mHeaderContainerParams.height=((int)(currentScale*PullToZoomListView.this.mHeaderHeight));
PullToZoomListView.this.mHeaderContainer.setLayoutParams(mHeaderContainerParams);
PullToZoomListView.this.post(this);//循环执行
}else{
Log.d(TAG,"ScalingRunnalablecurrentScale<1.0--中止");
this.mIsFinished=true;
}
}
}
publicvoidstartAnimation(longparamLong){
Log.d(TAG,"ScalingRunnalable开始执行动画");
this.mStartTime=SystemClock.currentThreadTimeMillis();
this.mDuration=paramLong;
this.mScale=((float)(PullToZoomListView.this.mHeaderContainer.getBottom())/PullToZoomListView.this.mHeaderHeight);
this.mIsFinished=false;
Log.d(TAG,"ScalingRunnalablethis.mStartTime="+this.mStartTime);
Log.d(TAG,"ScalingRunnalablethis.mDuration="+this.mDuration);
Log.d(TAG,"ScalingRunnalablethis.mScale="+this.mScale);
Log.d(TAG,"ScalingRunnalablethis.mIsFinished="+this.mIsFinished);
PullToZoomListView.this.post(this);
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。