从零開始开发Android版2048 (二)获取手势信息

       今天是尝试開始Android版2048小游戏的第二天。在今天,我主要学习了怎样获取用户在屏幕滑动的手势,以及对布局进行了一些小小的完好。

       获取用户操作的手势(比方向左滑。向右滑等)主要用到了GestureDetector。这个类能够帮助我们获取一些常见的用户对屏幕的操作。比如单击、双击、按压、拖动等。详细的使用说明。大家能够查API也能够去百度,或者看我之前有一篇使用GestureDetector实现的小样例(http://blog.csdn.net/xiapinnong/article/details/21970419)在这里就不多说了。


以下还是看代码吧。相对与第一篇,我在代码中主要增加一个内部类MygestureDetector。而且让这个类实现了OnTouchListener和OnGestureListener这两个接口。

当中OnTouchListener这个接口主要用来为我的GridLayout绑定对touch这个动作的监听,然后将详细的动作传递到GestureDetector。通过将用户详细的操作相应到不同的手势上。


	public class MygestureDetector implements OnGestureListener,OnTouchListener{

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			// TODO Auto-generated method stub		
			return gd.onTouchEvent(event);
		}

		@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) {
			
	        // 參数解释:      
	        // e1:第1个ACTION_DOWN MotionEvent      
	        // e2:最后一个ACTION_MOVE MotionEvent      
	        // velocityX:X轴上的移动速度,像素/秒      
	        // velocityY:Y轴上的移动速度。像素/秒      
	        
	        // 触发条件 :      
	        // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒    
			
			if(e1.getX()-e2.getX()>100){
				System.out.println("向左");
				return true;
			}else	if(e1.getX()-e2.getX()<-100){
				System.out.println("向右");
				return true;
			}else	if(e1.getY()-e2.getY()>100){
				System.out.println("向上");
				return true;
			}else	if(e1.getY()-e2.getY()<-00){
				System.out.println("向下");
				return true;
			}
			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) {
			// TODO Auto-generated method stub
			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;
		}
		
	}

onFiling()这个回调函数主要是指用户点击屏幕,并移动一小段距离。然后放开。

这种方法里的四个參数:

e1是指: 第1个ACTION_DOWN MotionEvent  

e2是指:  最后一个ACTION_MOVE MotionEvent     

velocityX:X轴上的移动速度,像素/秒     

  velocityY:Y轴上的移动速度。像素/秒  

(其他回调函数和參数的说明,能够參考这篇博客http://blog.csdn.net/xiapinnong/article/details/21970419


推断用户手指滑动的方向:

通过比較e1和e2这两个MotinEvent的坐标来计算的

比方e1的x坐标减去e2的x坐标大于零。说明用户的手指是向左滑动的


然后我们须要声明并初始化一个GestureDetector相应,并传入我们的MygestureDetector的对象,然后为我们的GridLayout绑定onTouchListener


完整的Activity代码例如以下:

package com.example.t2048;


import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.GridLayout;
import android.widget.ImageView;

public class MainActivity extends Activity {

	GridLayout gridLayout = null;
	
	//用于保存空格的位置
	List<Integer> spaceList = new ArrayList<Integer>();
	//用于保存有数字格的位置
	List<Integer> stuffList = new ArrayList<Integer>();
	
	GestureDetector gd = null;
	
	/**
	 * 图标数组
	 */
	private final int[] icons = { R.drawable.but_empty, R.drawable.but2,
			R.drawable.but4, R.drawable.but8, R.drawable.but16,
			R.drawable.but32, R.drawable.but64, R.drawable.but128,
			R.drawable.but256, R.drawable.but512, R.drawable.but1024,
			R.drawable.but2048, R.drawable.but4096 };
	
	protected void onCreate(Bundle savedInstanceState) {
		System.out.println("程序启动");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		gridLayout = (GridLayout) findViewById(R.id.GridLayout1);
		init();
		
		MygestureDetector mg = new MygestureDetector();

		gd = new GestureDetector(mg);
		gridLayout.setOnTouchListener(mg);
		gridLayout.setLongClickable(true);
		
	}
	
	//初始化界面
	public void init(){
		System.out.println("初始化");
		
		//首先在16个各种都填上空白的图片
		for(int i=0;i<16;i++){
			View view = View.inflate(this, R.layout.item, null);
			ImageView image = (ImageView) view.findViewById(R.id.image);
			
			image.setBackgroundResource(icons[0]);		
			spaceList.add(i);
			gridLayout.addView(view);	
		}
		
		//在界面中随机增加两个2或者4
		addRandomItem();
		addRandomItem();
	}
	
	//从空格列表中随机获取位置
	public int getRandomIndex(){
		Random random = new Random();
		if(spaceList.size()>0)
		 return random.nextInt(spaceList.size());
		else 
		 return -1;	
	}
	
	//在空白格中随机增加数字2
	public void addRandomItem(){
		int index = getRandomIndex();
		if(index!=-1){
			//获取相应坐标所相应的View
			View view = gridLayout.getChildAt(spaceList.get(index));
			ImageView image = (ImageView) view.findViewById(R.id.image);
			//随机生成数字1或2
			int i = (int) Math.round(Math.random()+1);
			//将当前格子的图片置换为2或者4
			image.setBackgroundResource(icons[i]);	
			//在空白列表中去掉这个格子
			spaceList.remove(index);
		}
	}
	
	public class MygestureDetector implements OnGestureListener,OnTouchListener{

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			// TODO Auto-generated method stub		
			return gd.onTouchEvent(event);
		}

		@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) {
			
	        // 參数解释:      
	        // e1:第1个ACTION_DOWN MotionEvent      
	        // e2:最后一个ACTION_MOVE MotionEvent      
	        // velocityX:X轴上的移动速度,像素/秒      
	        // velocityY:Y轴上的移动速度。像素/秒      
	        
	        // 触发条件 :      
	        // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒    
			
			if(e1.getX()-e2.getX()>100){
				System.out.println("向左");
				return true;
			}else	if(e1.getX()-e2.getX()<-100){
				System.out.println("向右");
				return true;
			}else	if(e1.getY()-e2.getY()>100){
				System.out.println("向上");
				return true;
			}else	if(e1.getY()-e2.getY()<-00){
				System.out.println("向下");
				return true;
			}
			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) {
			// TODO Auto-generated method stub
			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;
		}
		
	}

	
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

程序执行界面例如以下(界面比較难看):




用手指在GridLayout上滑动,在Log中能够打印出详细的滑动方向



原文地址:https://www.cnblogs.com/clnchanpin/p/6847169.html