根据滑动距离图片做缩放

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

二,原理分析

       图片缩放可以用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,关键在于设置透明度和缩放比例

        

@Override
	protected 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(){
			@Override
			public 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(){
			@Override
			public 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{

		@Override
		public boolean onDown(MotionEvent e) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			// TODO Auto-generated method stub
			return false;
		}

		@Override
		public void onLongPress(MotionEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			if(Math.abs(distanceY)<Math.abs(distanceX)/3){
				mTouchScalView.setRadius(distanceX);
			}
			return false;
		}

		@Override
		public void onShowPress(MotionEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			// TODO Auto-generated method stub
			return false;
		}
		
	}

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

@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		Thread[] 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;
	}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值