根据滑动距离图片做缩放

来源:互联网 发布:查询身份证归属地软件 编辑:程序博客网 时间:2024/05/12 17:09

一,闲来无事,写一个小东西练练手,首先看效果图

二,原理分析

       图片缩放可以用Matrix,渐变可以用Paint的alpha,再加上根据滑动距离的检测,就可以实现效果

三,源码地址:http://download.csdn.net/detail/u012155141/8915515

四,步骤解析

      1,自定义view,在构造方法中初始化一些属性

            

public TouchScalView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mMatrix = new Matrix();Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.bg_1);mBitmap = bitmap;viewWidth = mBitmap.getWidth();viewHeight = mBitmap.getHeight();mPaint = new Paint();initInvisibleThread();initVisibleThread();}
      2,重写onDraw,关键在于设置透明度和缩放比例

        

@Overrideprotected void onDraw(Canvas canvas) {mPaint.setAlpha(alpha);mMatrix.setScale((viewWidth + Radius) * 1f / viewWidth,(viewHeight + Radius) * 1f / viewHeight,viewWidth/2,viewHeight/2);canvas.drawBitmap(mBitmap, mMatrix, mPaint);super.onDraw(canvas);}
缩放比例为1时,就是原图大小,这里我们有一个变化的范围Radius,Radius在-viewWidth / 2和viewWidth/2中根据滑动距离变化。我们需要不停的

改变Radius的值,因此定义个接口,并对外公布一个方法,供调用。

public void setRadius(float dis) {isFinished = false;this.Radius += dis / 4;if (Radius > viewWidth / 2) {Radius = viewWidth / 2;isFinished = true;}if (Radius < -viewWidth / 2) {Radius = -viewWidth / 2;isFinished = true;}if(mFinishListener != null){mFinishListener.finished(isFinished);}alpha = (int) ((viewWidth / 2 + Radius) * 255 / viewWidth);invalidate();Log.i("AfterRadius", "" + Radius);}
public interface FinishListener{void finished(boolean isFinished);}public void setFinishListener(FinishListener listener){this.mFinishListener = listener;}
在构造方法中初始化时我们看到有两个方法,他们是当手松开时自动执行动画的两个显示,隐藏的线程

private void initVisibleThread() {visibleThread = new Thread(){@Overridepublic void run() {while (Radius <viewWidth / 2) {try {sleep(5);} catch (InterruptedException e) {e.printStackTrace();}Radius++;if (Radius > viewWidth / 2) {Radius = viewWidth / 2;}alpha = (int) ((viewWidth / 2 + Radius) * 255 / viewWidth);postInvalidate();}}};}private void initInvisibleThread() {inVisibleThread = new Thread(){@Overridepublic void run() {while (Radius >-viewWidth / 2) {try {sleep(5);} catch (InterruptedException e) {e.printStackTrace();}Radius--;if (Radius <-viewWidth / 2) {Radius = -viewWidth / 2;}alpha = (int) ((viewWidth / 2 + Radius) * 255 / viewWidth);postInvalidate();}}};}
ok,自定义的view完成,接下来就是在ontouchEvent中处理,首先,当手指按下滑动时我们用GestureDetector来处理,在onscroll方法中回调我们的接口

class IGestureDetector  implements OnGestureListener{@Overridepublic boolean onDown(MotionEvent e) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {// TODO Auto-generated method stubreturn false;}@Overridepublic void onLongPress(MotionEvent e) {// TODO Auto-generated method stub}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {if(Math.abs(distanceY)<Math.abs(distanceX)/3){mTouchScalView.setRadius(distanceX);}return false;}@Overridepublic void onShowPress(MotionEvent e) {// TODO Auto-generated method stub}@Overridepublic boolean onSingleTapUp(MotionEvent e) {// TODO Auto-generated method stubreturn false;}}

接下来在手指松开时,我们根据速度来执行在view中的autoInVisibleAnimation和autoVisibleAnimation方法。

@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubThread[] thds = mTouchScalView.getThreads();Thread thread0 = thds[0];Thread thread1 = thds[1];if(thread0.isAlive() ||thread1.isAlive()){return true;}mdDetector.onTouchEvent(event);if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();// 获得VelocityTracker类实例}mVelocityTracker.addMovement(event);// 将事件加入到VelocityTracker类实例中mVelocityTracker.computeCurrentVelocity(1000);int action = event.getAction();switch (action) {case MotionEvent.ACTION_DOWN:downX = (int) event.getX();break;case MotionEvent.ACTION_UP:int curX = (int) event.getX();float xVelocity = Math.abs(mVelocityTracker.getXVelocity());if (xVelocity > mMaximumVelocity) {xVelocity = mMaximumVelocity;}if(!isFinished){if(xVelocity>mMinimumVelocity){if(curX - downX>0){mTouchScalView.autoInVisibleAnimation();} else if(curX - downX<0){mTouchScalView.autoVisibleAnimation();}}}break;case MotionEvent.ACTION_CANCEL:mVelocityTracker.recycle();break;default:break;}return true;}


0 0
原创粉丝点击