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); } }以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。