用FrameLayout加OnToucherListener制作View切换动画

初学Android,由于只了解一些常见的View和布局,所以在做APP的过程中受到了很多限制,在经过对网上一些demo的参考之后,自己总结出可以通过FrameLayout加OnTouchListener编写出多种简单的切换效果。

用FrameLayout加OnToucherListener制作View切换动画_第1张图片

左图为没有切换动画时的界面,右图为view切换的界面,切换过程中切换动画会随着手指的滑动而滑动,当手指离开屏幕,某一个view会有动画重新占满全屏。

首先分析一下流程:手指触摸屏幕(ACTION_DOWN)->手指移动(ACTION_MOVE)->手指离开屏幕(ACTION_UP)->view自动充满屏幕

手指触摸屏幕:当手指触摸屏幕时,我们可以获取一个ACTION_DOWN事件,这个时候需要记录下当前的X坐标

	case MotionEvent.ACTION_DOWN:
			//获取最初点坐标的X
			preX = event.getX();
			break;

手指移动:当手指在屏幕上滑动时,我们可以持续获得一系列的ACTION_MOVE事件,通过当前事件的X坐标与ACTION_DOWN事件X坐标的差可以计算出当前的偏移量

	case MotionEvent.ACTION_MOVE:
			//获取当前view的偏移量
			offset = event.getX() - preX;

根据偏移量,计算出当前偏移占屏幕宽度的比例,这个比例用于缩放view以及改变view的透明度

		/**
		 * 获取view偏移相对于屏幕宽度的比例
		 */
		float scaleOffset = Math.abs(offset)/viewWidth;
		/**
		 * 当偏于比例大于最小偏移比例时,根据偏移比例缩放view;当偏移到一定程度时,view不再缩小
		 */
		float scaleFactor = Math.max(MIN_SCALE, Math.max(1 - scaleOffset, scaleOffset));
		/**
		 * 设定view的透明度
		 */
		float alpha = 0.4f+0.4f*(1-scaleFactor);
		float scaleAlpha = offset == 0 ? 1: alpha;

然后就根据比例缩放view,根据偏移量移动view

	currentView.setScaleX(scaleFactor);
        currentView.setScaleY(scaleFactor);
        currentView.setAlpha(scaleAlpha);
        currentView.setTranslationX(offset);
        nextView.setScaleX(scaleFactor);
        nextView.setScaleY(scaleFactor);
        nextView.setAlpha(scaleAlpha);
        nextView.setTranslationX(offset);
        lastView.setScaleX(scaleFactor);
        lastView.setScaleY(scaleFactor);
        lastView.setAlpha(scaleAlpha);
        lastView.setTranslationX(offset);
手指离开屏幕:当手指离开屏幕时,这个时候会获取到一个ACTION_UP事件,获取到这个事件时,我们就要判断是否切换当前view,我判断的标准是是否滑动超过屏幕的1/2

	case MotionEvent.ACTION_UP:
			//离开屏幕时根据偏移量判断是否切换view
			if(offset > viewWidth/2){
				handler.sendEmptyMessage(TO_RIGHT);
			}else if(offset < -viewWidth/2){
				handler.sendEmptyMessage(TO_LEFT);
			}else {
				handler.sendEmptyMessage(TO_CENTRE);
			}
view自动充满屏幕:当经过判断之后,如果滑动没有超过屏幕的1/2,那就让原来的view按照原来的路径从新充满屏幕;如果没有那就让下一个view按照进入屏幕的方向移动充满屏幕。充满屏幕这个过程,我是选用用Handler延时发送消息的方式进行的,当然也可以采用线程睡眠的方式。

		@Override
		public void handleMessage(Message message){
			super.handleMessage(message);
			Context context = this.context.get();
			if(context != null){
				switch(message.what){
				case TO_CENTRE:
					if(offset < 0 ){
						offset = offset + 30;
					}else{
						offset = offset - 30;
					}
					drawView(offset);
					if(Math.abs(offset)<30){
						offset = 0;
						drawView(offset);
					}else{
						sendEmptyMessageDelayed(TO_CENTRE, 5);
					}
					break;
				case TO_LEFT:
					offset = offset - 30;
					if(offset > -viewWidth){
						drawView(offset);
						sendEmptyMessageDelayed(TO_LEFT, 5);
					}else{
						offset = 0;
						initOrder(viewCentre, viewRight, viewLeft);
						drawView(offset);
						viewLeft = (viewLeft + 1) % 3;
						viewCentre = (viewCentre + 1) % 3;
						viewRight = (viewRight + 1) % 3;
					}
					break;
				case TO_RIGHT:
					offset = offset + 30;
					if(offset < viewWidth){	
						drawView(offset);
						sendEmptyMessageDelayed(TO_RIGHT, 5);
					}else{
						offset = 0;
						initOrder(viewRight, viewLeft, viewCentre);
						drawView(offset);
						viewLeft = (viewLeft + 2) % 3;
						viewCentre = (viewCentre + 2) % 3;
						viewRight = (viewRight + 2) % 3;
					}
					break;
				default:
					break;
				}
			}
		}
Demo下载地址






你可能感兴趣的:(AndroidView,动画,android,触摸屏,界面,app)