文档章节

Android中View的移动以及View之间的碰撞

fneg
 fneg
发布于 2014/03/18 23:16
字数 575
阅读 5728
收藏 3

        View的移动和碰撞检测的核心就在于如何获取到View在屏幕中的位置,获取的方法很多,本文中直接使用View.getX() View.getY()方法获取到左上角的顶点位置,View之间的碰撞检测就是在View的移动过程中不断计算和特定View之间的距离。代码如下:

import android.content.Context;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

public class TouchMoveView extends RelativeLayout {
	private static final String TAG="TouchMoveView";
	private View mTargetView;
	private View mRedView, mBlueView, mGreenView, mYellowView;
	private RectF mRedRect,mBlueRect,mGreenRect,mYellowRect,mTargetRect;
	
	private View mParentView;
	public TouchMoveView(Context context) {
		this(context, null);
	}

	public TouchMoveView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		mTargetView = findViewById(R.id.target_view);
		mRedView = findViewById(R.id.red);
		mBlueView = findViewById(R.id.blue);
		mGreenView = findViewById(R.id.green);
		mYellowView = findViewById(R.id.yellow);
		
		mParentView=findViewById(R.id.parent_view);
	}
	
	private View mTouchedView;
	private float mInitX;
	private float mInitY;
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		initRect();
		float x=event.getX();
		float y=event.getY();
		int action=event.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			mTouchedView=getTouchedView((int)x, (int)y);
			if(null!=mTouchedView){
				mInitX=mTouchedView.getX();
				mInitY=mTouchedView.getY();
			}
			Log.e(TAG,"mTouchedView:"+mTouchedView);
			return true;
		case MotionEvent.ACTION_MOVE:
			if(null!=mTouchedView){
				float moveX=x-mTouchedView.getWidth()/2;
				float moveY=y-mTouchedView.getHeight()/2;
				Log.e(TAG,"moveX:"+moveX+"  moveY:"+moveY );
				mTouchedView.setX(moveX);
				mTouchedView.setY(moveY);
				
				if(isTwoViewClose(mTouchedView, mTargetView)){
					int colorRes=getColorRes(mTouchedView);
					mTargetView.setBackgroundColor(getResources().getColor(colorRes));
				}else{
					mTargetView.setBackgroundColor(getResources().getColor(R.color.black));
				}
			}
			return true;
		
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			if(null!=mTouchedView){
				mTouchedView.setX(mInitX);
				mTouchedView.setY(mInitY);
			}
			mTargetView.setBackgroundColor(getResources().getColor(R.color.black));
			return true;
		default:
			return false;
		}
	}
	private int getColorRes(View view){
		if(null==view){
			return R.color.black;
		}
		int id=view.getId();
		switch (id) {
		case R.id.blue:
			return R.color.blue;
		case R.id.red:
			return R.color.red;
		case R.id.green:
			return R.color.green;
		case R.id.yellow:
			return R.color.yellow;
		default:
			return R.color.black;
		}
	}
	
	private View getTouchedView(int x,int y){
		Log.e(TAG,"x:"+x+" y:"+y);
		Log.e(TAG,"mRedRect"+mRedRect);
		Log.e(TAG,"mBlueRect"+mBlueRect);
		Log.e(TAG,"mGreenRect"+mGreenRect);
		Log.e(TAG,"mYellowRect"+mYellowRect);
		if(mRedRect.contains(x, y)){
			return mRedView;
		}
		
		if(mBlueRect.contains(x, y)){
			return mBlueView;
		}
		
		if(mGreenRect.contains(x, y)){
			return mGreenView;
		}
		
		if(mYellowRect.contains(x, y)){
			return mYellowView;
		}
		return null;
		
	}
	private void initRect(){
		if(null==mRedRect){
			mRedRect=getRect(mRedView);
		}
		
		if(null==mBlueRect){
			mBlueRect=getRect(mBlueView);
		}
		if(null==mGreenRect){
			mGreenRect=getRect(mGreenView);
		}
		if(null==mYellowRect){
			mYellowRect=getRect(mYellowView);
		}
		if(null==mTargetRect){
			mTargetRect=getNormalRect(mTargetView);
		}
	}
	private RectF getNormalRect(View view){
		return new RectF(view.getX(),view.getY(),view.getX()+view.getWidth(),view.getY()+view.getHeight());
	}
	
	private RectF getRect(View view){
		RectF rectf=new RectF(view.getX(),view.getY()+mParentView.getY(),view.getX()+view.getWidth(),view.getY()+mParentView.getY()+view.getHeight());
		return rectf;
	}
	/**判断两个View是否相交
	 * @param src
	 * @param target
	 * @return
	 */
	private boolean isTwoViewClose(View src,View target){
		RectF rectSrc=getNormalRect(src);
		RectF rectTar=getNormalRect(target);
		return rectSrc.intersect(rectTar);
	}

项目地址:http://git.oschina.net/fengcunhan/TouchMove.git

© 著作权归作者所有

fneg

fneg

粉丝 76
博文 43
码字总数 23812
作品 0
杭州
高级程序员
私信 提问
加载中

评论(2)

fneg
fneg 博主

引用来自“于宝剑”的评论

看见丰师兄的博客了!!!!!
于宝剑
于宝剑
看见丰师兄的博客了!!!!!
Android开发之漫漫长途 XVII——动画

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ...

马飞标
2018/08/09
0
0
Android SDK 实例代码分析---Accelerometer Play(三)

三.资源说明 3.1 图片资源 1.高分辨率图片 ball.png------震动传感器使用的球体图片。 icon------本应用程序的图标(在高分辨率屏幕上使用)。 wood.jpg------应用程序主窗口背景。 2. 中分辨...

长平狐
2012/10/16
1K
0
Android视图动画---View Animation

本文译自:http://developer.android.com/guide/topics/graphics/view-animation.html 你能够使用视图动画系统来执行View对象上的补间动画。补间动画是用诸如开始点、结束点、尺寸、旋转以及...

长平狐
2012/10/16
321
0
安卓(Android)系统的检测方法

我发现自己有两篇博客的关注度在与日俱增:《通过JS或PHP检测iPad设备》以及《通过JS或PHP检测iPhone和iPad设备》。看来移动端的开发话题越来越火热了。在此列出一些能够在iOS的最大竞争者—...

网络营销
2012/02/16
97
0
Android属性动画---Property Animation(六)

对于ViewGroups对象布局变化的动画 属性动画系统给ViewGroup对象的动画变化提供了与View对象一样容易动画处理方法。 使用LayoutTransition类在ViewGroup内部处理布局变化的动画。当调用一个V...

长平狐
2012/10/16
200
0

没有更多内容

加载失败,请刷新页面

加载更多

iOS苹果应用IPA一键签名工具及重签教程

开心签名工具,是一款跨平台ios签名和重签名工具。 同时支持在windows、linux、mac运行,数据同步,方便使用及管理! 开心重签名工具官网 功能特点 1、支持图形界面及命令行重签(部署到服务...

tintong
10分钟前
3
0
2.4G有源卡核心芯片供应商

有源2.4G RFID的防盗标签,在与无源标签相比较,通信距离远,通信时效高。我司的SI24R2E这颗芯片专门为2.4G有源标签而设计,具有低功耗,发送距离远,厂商设计简单等优势;广泛应用于现在城市...

文刀石
15分钟前
2
0
设置Ubuntu16.04启动为命令行界面

1. 修改/etc/default/grub文件,将GRUB_CMDLINE_LINUX_DEFAULT设置成”quiet splash 3” 2. 使用命令update-grub使得在/boot下重新生成GRUB2配置文件。 3. 重启...

JosiahMg
16分钟前
2
0
C++基础知识点

计算机语言 计算机不能理解高级语言,只能理解机器语言,必须要将高级语言翻译成机器语言,翻译的方式有两种,一种是编译,一种是解释 解释型语言,在运行程序时进行翻译,每个语句在执行时逐...

大瑞清_liurq
22分钟前
2
0
EFCore 多条数据更新不能同时savechanges()的解决方法

1 在ModelContext定义下增加var transaction = ctx.Database.BeginTransaction(); 1.2 在最后一个SaveChanges()后增加transaction.Commit(); 3 在finally的if (sMsgCode != "")分支中增加tra......

_Somuns
26分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部