• 从零開始开发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中能够打印出详细的滑动方向



  • 相关阅读:
    linux解释器、内建和外建命令
    linux文件cat/tac/more/less/head/tail/find/vimdiff
    zk和eureka的区别(CAP原则)
    Hystrix断路器中的服务熔断与服务降级
    windows 查看端口被占用,解除占用
    JS中操作JSON总结
    Ajax请求($.ajax()为例)中data属性传参数的形式
    通过 Ajax 发送 PUT、DELETE 请求的两种实现方式
    feignclient发送get请求,传递参数为对象
    Spring Boot 和 Spring Cloud Feign调用服务及传递参数踩坑记录
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6847169.html
Copyright © 2020-2023  润新知