手势事件处理MotionEvent是智能手机的一大特性,即可用于信息输出(显示界面)又可用于输入(检测用户的触摸行为)。为了方便开发者使用,Android已经自动识别特定的几种触摸手势,包括按钮的点击事件OnClickListener、长按事件OnLongClickListener、滚动视图ScrollView的上下滚动事件、翻页视图ViewPager的左右翻页事件等。
其中dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent的输入参数都是手势事件MotionEvent,其中包含触摸动作的所有信息,各种手势操作都得到MotionEvent中获取信息并进行判断处理。以下是演示单点触摸的代码实现:
- layout/activity_touch_single.xml界面布局代码如下:
package com.fukaimei.touchevent;
import java.util.Date;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.widget.TextView;
public class TouchSingleActivity extends AppCompatActivity {
private TextView tv_touch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_touch_single);
tv_touch = (TextView) findViewById(R.id.tv_touch);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 从开机到现在的毫秒数
int seconds = (int) (event.getEventTime() / 1000);
int hour = seconds / 3600;
int minute = seconds % 3600 / 60;
int second = seconds % 60;
Date date = new Date(event.getEventTime());
String desc = String.format("动作发生时间:开机距离现在%02d:%02d:%02d",
hour, minute, second);
desc = String.format("%s\n动作名称是:", desc);
int action = event.getAction();
if (action == event.ACTION_DOWN) {
desc = String.format("%s按下", desc);
} else if (action == event.ACTION_MOVE) {
desc = String.format("%s移动", desc);
} else if (action == event.ACTION_UP) {
desc = String.format("%s提起", desc);
} else if (action == event.ACTION_CANCEL) {
desc = String.format("%s取消", desc);
}
desc = String.format("%s\n动作发生位置是:横坐标%f,纵坐标%f",
desc, event.getX(), event.getY());
tv_touch.setText(desc);
return super.onTouchEvent(event);
}
}
- TouchSingleActivity.java逻辑代码如下:
package com.fukaimei.touchevent;
import java.util.Date;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.widget.TextView;
public class TouchSingleActivity extends AppCompatActivity {
private TextView tv_touch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_touch_single);
tv_touch = (TextView) findViewById(R.id.tv_touch);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 从开机到现在的毫秒数
int seconds = (int) (event.getEventTime() / 1000);
int hour = seconds / 3600;
int minute = seconds % 3600 / 60;
int second = seconds % 60;
Date date = new Date(event.getEventTime());
String desc = String.format("动作发生时间:开机距离现在%02d:%02d:%02d",
hour, minute, second);
desc = String.format("%s\n动作名称是:", desc);
int action = event.getAction();
if (action == event.ACTION_DOWN) {
desc = String.format("%s按下", desc);
} else if (action == event.ACTION_MOVE) {
desc = String.format("%s移动", desc);
} else if (action == event.ACTION_UP) {
desc = String.format("%s提起", desc);
} else if (action == event.ACTION_CANCEL) {
desc = String.format("%s取消", desc);
}
desc = String.format("%s\n动作发生位置是:横坐标%f,纵坐标%f",
desc, event.getX(), event.getY());
tv_touch.setText(desc);
return super.onTouchEvent(event);
}
}
- Demo程序运行效果界面截图如下:
除了单点触摸外,智能手机还普通支持多点触控,即响应两个及以上手指同时按压屏幕。多点触控可用于操纵图像的缩放与旋转操作,以及需要多点处理的游戏界面等。
下面是演示多点触控的页面代码:
- layout/activity_touch_multiple.xml界面布局代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/tv_touch_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这里显示主要点触摸结果"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_touch_secondary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这里显示次要点触摸结果"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
- TouchMultipleActivity.java逻辑代码如下:
package com.fukaimei.touchevent;
import java.util.Date;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.widget.TextView;
public class TouchMultipleActivity extends AppCompatActivity {
private TextView tv_touch_main;
private TextView tv_touch_secondary;
private boolean bSecondaryPressed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_touch_multiple);
tv_touch_main = (TextView) findViewById(R.id.tv_touch_main);
tv_touch_secondary = (TextView) findViewById(R.id.tv_touch_secondary);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int seconds = (int) (event.getEventTime() / 1000);
int hour = seconds / 3600;
int minute = seconds % 3600 / 60;
int second = seconds % 60;
Date date = new Date(event.getEventTime());
String desc_main = String.format("主要动作发生时间:开机距离现在%02d:%02d:%02d\n%s",
hour, minute, second, "主要动作名称是:");
String desc_secondary = "";
int action = event.getAction() & MotionEvent.ACTION_MASK;
if (action == event.ACTION_DOWN) {
desc_main = String.format("%s按下", desc_main);
} else if (action == event.ACTION_MOVE) {
desc_main = String.format("%s移动", desc_main);
if (bSecondaryPressed == true) {
desc_secondary = String.format("%s次要动作名称是:移动", desc_secondary);
}
} else if (action == event.ACTION_UP) {
desc_main = String.format("%s提起", desc_main);
} else if (action == event.ACTION_CANCEL) {
desc_main = String.format("%s取消", desc_main);
} else if (action == event.ACTION_POINTER_DOWN) {
bSecondaryPressed = true;
desc_secondary = String.format("%s次要动作名称是:按下", desc_secondary);
} else if (action == event.ACTION_POINTER_UP) {
bSecondaryPressed = false;
desc_secondary = String.format("%s次要动作名称是:提起", desc_secondary);
}
desc_main = String.format("%s\n主要动作发生位置是:横坐标%f,纵坐标%f",
desc_main, event.getX(), event.getY());
tv_touch_main.setText(desc_main);
if (bSecondaryPressed == true || desc_secondary.length() > 0) {
desc_secondary = String.format("%s\n次要动作发生位置是:横坐标%f,纵坐标%f",
desc_secondary, event.getX(1), event.getY(1));
tv_touch_secondary.setText(desc_secondary);
}
return super.onTouchEvent(event);
}
}
- Demo程序运行效果界面截图如下: