今天是尝试開始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中能够打印出详细的滑动方向

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhcGlubm9uZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">

从零開始开发Android版2048 (二)获取手势信息的更多相关文章

  1. 从零開始开发Android版2048 (一)初始化界面

    自学Android一个月多了,一直在工作之余零零散散地看一些东西.感觉经常使用的东西都有些了解了,可是一開始写代码总会出各种奇葩的问题.感觉还是代码写得太少.这样继续杂乱地学习下去进度也太慢了,并且学 ...

  2. 从零開始开发Android版2048 (四) 分数、重置、结束

    这一篇的内容主要是在上一篇的基础上,增加分数计算(包含当前分数和最高分数).游戏结束的推断以及游戏界面的重置这三个部分的功能. 一.分数的计算和保存          首先,2048这个游戏的分数包含 ...

  3. 从零開始开发Android版2048 (三)逻辑推断

    近期工作比較忙,所以更新的慢了一点,今天的主要内容是关于Android版2048的逻辑推断,经过本篇的解说,基本上完毕了这个游戏的主体部分. 首先还是看一下,我在实现2048时用到的一些存储的数据结构 ...

  4. 从零開始开发Android版2048 (五) 撤销的实现

    本篇的内容是,在前一篇的基础上添�了撤销的功能.撤销事实上就是将当前的用户界面恢复到这次滑动值前的样子.我实现撤销的主要原理是,将每次滑动后界面上的格子和相应的数字记录下来,当然还有分数,把这些数据写 ...

  5. 从零開始学android&lt;TabHost标签组件.二十九.&gt;

    TabHost主要特点是能够在一个窗体中显示多组标签栏的内容,在Android系统之中每一个标签栏就称为一个Tab.而包括这多个标签栏的容器就将其称为TabHost.TabHost类的继承结构例如以下 ...

  6. 第13章、布局Layouts之RelativeLayout相对布局(从零開始学Android)

    RelativeLayout相对布局 RelativeLayout是一种相对布局,控件的位置是依照相对位置来计算的,后一个控件在什么位置依赖于前一个控件的基本位置,是布局最经常使用,也是最灵活的一种布 ...

  7. 从零開始学android&lt;SeekBar滑动组件.二十二.&gt;

    拖动条能够由用户自己进行手工的调节,比如:当用户须要调整播放器音量或者是电影的播放进度时都会使用到拖动条,SeekBar类的定义结构例如以下所看到的: java.lang.Object    ↳ an ...

  8. 从零開始学android&lt;数据存储(1)SharedPreferences属性文件.三十五.&gt;

    在android中有五种保存数据的方法.各自是: Shared Preferences Store private primitive data in key-value pairs. 相应属性的键值 ...

  9. 从零開始学android&lt;mediaplayer自带播放器(视频播放).四十九.&gt;

    MediaPlayer除了能够对音频播放之外,也能够对视频进行播放,可是假设要播放视频仅仅依靠MediaPlayer还是不够的.还须要编写一个能够用于视频显示的空间,而这块显示空间要求能够高速的进行G ...

随机推荐

  1. webdriver高级应用- 操作日期控件

    1. 通过点击的方式操作日期控件 #encoding=utf-8 from selenium import webdriver import unittest, time, traceback fro ...

  2. Linux删除非空目录的方法

    rmdir 无法删除非空目录. rm -rf 可以递归,强制,删除目录

  3. java EE技术体系——CLF平台API开发注意事项(2)——后端测试

    前言:上篇博客说到了关于开发中的一些情况,这篇博客主要说明一些关于测试的内容. 一.宏观说明 要求:每一个API都必须经过测试.   备注:如果涉及到服务间调用(如权限和基础数据),而对方服务不可用时 ...

  4. linux磁盘问题排查

    一.ls $>>ls /data* //查看有无input/output error报错 二.demsg $>>demsg|grep sd 问题盘结果: 三.iostat使用 ...

  5. 【bzoj4310】跳蚤 后缀数组+二分

    题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...

  6. CSS3的writing-mode属性

    writing-mode这个CSS属性以前是IE的独有属性,IE5.5浏览器就已经支持了.在很长一段时间里,FireFox, Chrome这些现代浏览器都不支持writing-mode,各大现代浏览器 ...

  7. BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】

    题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...

  8. hdu 3613 KMP算法扩展

    Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  9. 视音频数据处理入门:RGB、YUV像素数据处理【转】

    转自:http://blog.csdn.net/leixiaohua1020/article/details/50534150 ==================================== ...

  10. 變更 cut-off,termination current,截止電流 對 battery capacity 的影響

    依之前的經驗 2700mAh 電池 cut-off 由 128 降至 64 mA,充電時間延長 20 分鐘, (128 + 64)/2 = 96 取平均充電流, 96 * (20/60) = 32 m ...