本文实例为大家分享了AndroID九宫格图片展示的具体代码,供大家参考,具体内容如下
在git上查看牛人的代码,发现是反编译别人的代码,还没加注释,代码也没有完全编译完整,所以这里我做的简单的注释,仅供学习。
变量说明
这里变量包含了:自定义返回动画加速度、自定义动画线程、头部图片vIEw,最后的y坐标,做好的比例,做大的比例等。
private static final String TAG = "PullToZoomListVIEw"; private static final int INVALID_VALUE = -1;//重置值 //自定义加速度动画 private static final Interpolator sInterpolator = new Interpolator() { public float getInterpolation(float interpolator) { float f = interpolator - 1.0F; return 1.0F + f * (f * (f * (f * f))); } }; private int mActivePointerID = INVALID_VALUE;//当前手指的ID private FrameLayout mheaderContainer;//头部 private int mheaderHeight;//头部图片的高度 private ImageVIEw mheaderImage;//头部图片 float mLastMotionY = INVALID_VALUE;//最后y坐标 float mLastScale = INVALID_VALUE;//最后的比例 float mMaxScale = INVALID_VALUE;//最大的比例 private OnScrollListener mOnScrollListener;//滑动监听 private ScalingRunnalable mScalingRunnalable;//动画线程 private int mScreenHeight;//屏幕高度 private ImageVIEw mShadow;//阴影遮罩
自定义view初始化:设置了头部的头部和遮罩并且设置了监听。
/** * 初始化 * @param paramContext */ private voID init(Context paramContext) { displayMetrics metrics = new displayMetrics(); ((Activity) paramContext).getwindowManager().getDefaultdisplay().getMetrics(metrics); this.mScreenHeight = metrics.heightPixels;//屏幕高度赋值 this.mheaderContainer = new FrameLayout(paramContext);//头部 this.mheaderImage = new ImageVIEw(paramContext);//头部图片 int screenWIDth = metrics.wIDthPixels;//屏幕宽度 //设置头部VIEw的样式 设置屏幕宽度,最大样式高度为屏幕高度的9/16 setheaderVIEwSize(screenWIDth,(int) (9.0F * (screenWIDth / 16.0F))); this.mShadow = new ImageVIEw(paramContext);//遮罩 FrameLayout.LayoutParams layoutParams = new FrameLayout.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 = new ScalingRunnalable(); //设置监听 super.setonScrollListener(this); }
开启动画:判断当前的头部布局底部的位置C是否大于图片的初始化高度。
/** * 开启动画 */ private voID endScraling() { if (this.mheaderContainer.getBottom() >= this.mheaderHeight) { Log.d(TAG,"this.mScalingRunnalable.startAnimation(200L)"); this.mScalingRunnalable.startAnimation(200L); } }
多指触碰时将第0个手指赋值。
/** * 多点触碰的时候按下,当第0个有手指抬起,再次有手指按下后,将按下的事件的手指指针作为当前手指指针 * * @param motionEvent */ private voID onSecondaryPointerUp(MotionEvent motionEvent) { Log.d(TAG,"onSecondaryPointerUp motionEvent.getPointerID(0) = " + motionEvent.getPointerID(0)); Log.d(TAG,"onSecondaryPointerUp this.mActivePointerID = " + this.mActivePointerID); if (motionEvent.getPointerID(0) == this.mActivePointerID) { this.mLastMotionY = motionEvent.getY(0); this.mActivePointerID = motionEvent.getPointerID(0); } Log.d(TAG,"onSecondaryPointerUp mLastMotionY = " + mLastMotionY); Log.d(TAG,"onSecondaryPointerUp mActivePointerID = " + mActivePointerID); }
重置所有的数据
/** * 重置所有数据*/ private voID reset() { this.mActivePointerID = INVALID_VALUE; this.mLastMotionY = INVALID_VALUE; this.mMaxScale = INVALID_VALUE; this.mLastScale = INVALID_VALUE; }
向上滚动时修改布局样式
@OverrIDe public voID onScroll(AbsListVIEw vIEw,int firstVisibleItem,int visibleItemCount,int totalitemCount) { Log.d(TAG,"onScroll"); float bottomSpacing = this.mheaderHeight - this.mheaderContainer.getBottom(); Log.d(TAG,"onScroll bottomSpacing = " + bottomSpacing); if ((bottomSpacing > 0.0F) && (bottomSpacing < this.mheaderHeight)) {//如果是向上滑动 int toUpScroll = (int) (0.65D * bottomSpacing); this.mheaderImage.scrollTo(0,-toUpScroll); Log.d(TAG,"onScroll 向上滑动 toUpScroll = " + toUpScroll); } else if (this.mheaderImage.getScrollY() != 0) { Log.d(TAG,"onScroll this.mheaderImage.getScrollY() = " + this.mheaderImage.getScrollY()); this.mheaderImage.scrollTo(0,0); } if (this.mOnScrollListener != null) { this.mOnScrollListener.onScroll(vIEw,firstVisibleItem,visibleItemCount,totalitemCount); } }
不同事件处理,修改布局样式
@OverrIDe public boolean ontouchEvent(MotionEvent motionEvent) { switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_OUTSIDE: case MotionEvent.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,"ontouchEvent ACTION_DOWN mLastMotionY = " + mLastMotionY); Log.d(TAG,"ontouchEvent ACTION_DOWN mActivePointerID = " + mActivePointerID); Log.d(TAG,"ontouchEvent ACTION_DOWN mMaxScale = " + mMaxScale); Log.d(TAG,"ontouchEvent ACTION_DOWN mLastScale = " + mLastScale); break; case MotionEvent.ACTION_MOVE: Log.d(TAG,"ontouchEvent ACTION_MOVE mActivePointerID" + mActivePointerID); //获取当前ID的手机指针 int pointer = motionEvent.findPointerIndex(this.mActivePointerID); //判断指针不为空 if (pointer == INVALID_VALUE) { Log.e(TAG,"InvalID pointerID=" + this.mActivePointerID + " in ontouchEvent"); } else { //如果开始没有赋值,则需要赋值 if (this.mLastMotionY == INVALID_VALUE) { this.mLastMotionY = motionEvent.getY(pointer); } if (this.mheaderContainer.getBottom() >= this.mheaderHeight) { //获取头部样式 VIEwGroup.LayoutParams headerParams = this.mheaderContainer.getLayoutParams(); float currentScale = ((motionEvent.getY(pointer) - this.mLastMotionY + this.mheaderContainer.getBottom()) / this.mheaderHeight - this.mLastScale) / 2.0F + this.mLastScale; if ((this.mLastScale <= 1.0D) && (currentScale < this.mLastScale)) { //最后比例小于默认并且当前的比例要小于上次的比例,则修改头部的高度 headerParams.height = this.mheaderHeight; this.mheaderContainer.setLayoutParams(headerParams); return super.ontouchEvent(motionEvent); } else { //否则,将当前的比例赋值为最后一次的比例 this.mLastScale = Math.min(Math.max(currentScale,1.0F),this.mMaxScale); headerParams.height = ((int) (this.mheaderHeight * this.mLastScale)); //判断修改后的高度小于屏幕的高度 if (headerParams.height < this.mScreenHeight) { this.mheaderContainer.setLayoutParams(headerParams); } //记录最后的y坐标 this.mLastMotionY = motionEvent.getY(pointer); return true; } } this.mLastMotionY = motionEvent.getY(pointer); } break; case MotionEvent.ACTION_UP: Log.d(TAG,"ontouchEvent ACTION_UP 重置"); //重置 reset(); //当手指起来的时候,结算拉伸,判断是否开启动画 endScraling(); break; case MotionEvent.ACTION_CANCEL: int actionIndex = motionEvent.getActionIndex();//获取当前最上层的指针 this.mLastMotionY = motionEvent.getY(actionIndex);//获取最后的y坐标 this.mActivePointerID = motionEvent.getPointerID(actionIndex);//获取最上层指针的手指 Log.d(TAG,"ontouchEvent ACTION_CANCEL actionIndex = " + actionIndex + " mLastMotionY = " + mLastMotionY + " mActivePointerID = " + mActivePointerID); break; case MotionEvent.ACTION_POINTER_DOWN: //当第二个手指按下或者放开触发这个事件 onSecondaryPointerUp(motionEvent); this.mLastMotionY = motionEvent.getY(motionEvent.findPointerIndex(this.mActivePointerID)); Log.d(TAG,"ontouchEvent_Po ACTION_POINTER_DOWN mLastMotionY = " + mLastMotionY); break; case MotionEvent.ACTION_POINTER_UP: //当第二个手指按下或者放开 Log.d(TAG,"ontouchEvent_Po ACTION_POINTER_UP "); break; } return super.ontouchEvent(motionEvent); }
向上返回时的动画
/** * 向上返回的动画 */ class ScalingRunnalable implements Runnable { long mDuration;//持续时间 boolean mIsFinished = true;//是否结束 float mScale;//比例 long mStartTime;//开始时间 ScalingRunnalable() { } /** * 中止动画 */ public voID abortAnimation() { this.mIsFinished = true; } /** * 是否中止 * * @return */ public boolean isFinished() { return this.mIsFinished; } public voID run() { Log.d(TAG,"ScalingRunnalable mIsFinished = " + this.mIsFinished + " this.mScale = " + this.mScale); float currentScale; VIEwGroup.LayoutParams mheaderContainerParams;//头部样式 //判断是否中止和已经滑动超过的默认大小 if ((!this.mIsFinished) && (this.mScale > 1.0D)) { float currentTime = ((float) SystemClock.currentThreadTimeMillis() - (float) this.mStartTime) / (float) this.mDuration; currentScale = this.mScale - (this.mScale - 1.0F) * PullToZoomListVIEw.sInterpolator.getInterpolation(currentTime); Log.d(TAG,"ScalingRunnalable currentTime = " + currentTime + " currentScale = " + currentScale); mheaderContainerParams = PullToZoomListVIEw.this.mheaderContainer.getLayoutParams(); if (currentScale > 1.0F) { Log.d(TAG,"ScalingRunnalable currentScale > 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,"ScalingRunnalable currentScale < 1.0 -- 中止"); this.mIsFinished = true; } } } public voID startAnimation(long paramLong) { 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,"ScalingRunnalable this.mStartTime = " + this.mStartTime); Log.d(TAG,"ScalingRunnalable this.mDuration = " + this.mDuration); Log.d(TAG,"ScalingRunnalable this.mScale = " + this.mScale); Log.d(TAG,"ScalingRunnalable this.mIsFinished = " + this.mIsFinished); PullToZoomListVIEw.this.post(this); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
以上是内存溢出为你收集整理的Android ListView实现下拉顶部图片变大效果全部内容,希望文章能够帮你解决Android ListView实现下拉顶部图片变大效果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)