继续上次未完成的手势封装:
还是直接代码:
手势类别:
/**
* 枚举类型
* 说明到底需要判断的手势有哪些
* 只判断Y轴,只判断X轴,或者Y轴X轴都要判断
* @author Administrator
*
*/
public enum GestureType {
/**
* 只判断Y轴
*/
GESTURE_ONLY_Y,
/**
* 只判断X轴
*/
GESTURE_ONLY_X,
/**
* 同时判断X轴和Y轴
*/
GESTURE_BOTH_XY,
/**
* 不仅仅判断x轴 ,y轴,
* 同时判断y轴是在左半屏幕滑动还是右半屏幕滑动
*/
GESTURE_X_LEFTY_RIGHTY;
}
手势动作类型:
public class TouchActionType {
/**
* 手指接触到屏幕
*/
public static final int ACTION_TOUCH_DOWN = 0x0001;
/**
* 手指从屏幕上拿起
*/
public static final int ACTION_TOUCH_UP = 0x0002;
/**
* X轴左滑手势
*/
public static final int ACTION_X_LEFT = 0x0003;
/**
* X轴右滑手势
*/
public static final int ACTION_X_RIGHT = 0x0004;
/**
* Y轴上拉手势 如上拉加载更多
*/
public static final int ACTION_Y_UP = 0x0005;
/**
* Y轴下拉手势,如下拉刷新
*/
public static final int ACTION_Y_DOWN = 0x0006;
/**
* Y轴上拉手势 左屏
*/
public static final int ACTION_Y_LEFT_UP = 0x0007;
/**
* Y轴下拉手势 左屏
*/
public static final int ACTION_Y_LEFT_DOWN = 0x0008;
/**
* Y轴上拉手势 右屏
*/
public static final int ACTION_Y_RIGHT_UP = 0x0009;
/**
* Y轴下拉手势 右屏
*/
public static final int ACTION_Y_RIGHT_DOWN = 0x0010;
}
手势管理关键类,重写 ontouchlistener,你可以选择是否让事件传递到下层继续处理,在listview等有滑动事件中,必须设置为FALSE,否则会出现控件的滑动事件冲突:
使用 setWithoutOther(boolean flag)方法来设置。
import android.annotation.SuppressLint;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class KindlionOnTouchListener implements OnTouchListener {
/**
* 开始时候的X坐标
*/
private float startX = 0;
/**
* 开始时候的Y坐标
*/
private float startY = 0;
/**
* 用于传递消息的句柄
*/
private Handler mHandler;
/**
* 当前判定的手势是什么
*/
private int currentAction = 0;
/**
* 默认为Y轴的滑动判断
*/
private GestureType Type = GestureType.GESTURE_ONLY_Y;
/**
* 当前手势是否已锁定
*/
private boolean isLocked = false;
/**
* 滑动的最小距离
*/
private static final int minDistance = 20;
/**
* 屏幕宽度
*/
private int screenWidth = 0;
/**
* touch事件返回值
*/
private boolean withoutOther = true;
/**
* 构造方法
* @param mHandler 传入消息句柄
* @param Type 手势类型
*/
public KindlionOnTouchListener(Handler mHandler,GestureType Type) {
this.mHandler = mHandler;
this.Type = Type;
}
@SuppressLint("ClickableViewAccessibility") @Override
public boolean onTouch(View v, MotionEvent event) {
screenWidth = v.getWidth();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isLocked = false;
startX = event.getX();
startY = event.getY(); //获取当前的Y坐标
currentAction = TouchActionType.ACTION_TOUCH_DOWN;
mHandler.sendEmptyMessage(currentAction);
break;
case MotionEvent.ACTION_MOVE:
float moveX = event.getX();
float moveY = event.getY(); //获取移动的时候的Y坐标
PDAciton(moveX,moveY);
break;
case MotionEvent.ACTION_UP:
isLocked = false;
currentAction = TouchActionType.ACTION_TOUCH_UP;
mHandler.sendEmptyMessage(currentAction);
break;
default:
break;
}
return withoutOther;
}
public boolean isWithoutOther() {
return withoutOther;
}
/**
*
* @param withoutOther
*/
public void setWithoutOther(boolean withoutOther) {
this.withoutOther = withoutOther;
}
/**
* 判断当前的手势动作
* @param moveX 手指在x轴滑动到距离
* @param moveY 手指在y轴滑动到距离
*/
private void PDAciton(float moveX,float moveY) {
if(isLocked){ //当前动作已经判断完毕,不做任何操作
return;
}
float gapX = moveX - startX; //和上一次X轴的差距
float gapY = moveY - startY; //和上一次Y轴的差距
switch (Type) {
case GESTURE_ONLY_Y:
if(Math.abs(gapY) < minDistance){ //滑动距离过小,不予理会
// Log.e("sssssssssss", "距离过小!"+gapY);
return;
}
DoOnlyY(gapY);
break;
case GESTURE_ONLY_X:
if(Math.abs(gapX) < minDistance){ //滑动距离过小,不予理会
// Log.e("sssssssssss", "距离过小!"+gapX);
return;
}
DoOnlyX(gapX);
break;
case GESTURE_BOTH_XY:
if(Math.abs(gapX) < minDistance && Math.abs(gapY) < minDistance){ //滑动距离过小,不予理会
return;
}
DoBothXY(gapX,gapY);
break;
case GESTURE_X_LEFTY_RIGHTY:
if(Math.abs(gapX) < minDistance && Math.abs(gapX) < minDistance){ //滑动距离过小,不予理会
// Log.e("sssssssssss", "距离过小!");
return;
}
// Log.e("sssssssssss", "距里合适!");
DoXAndLYAndRY(gapX,gapY);
break;
default:
break;
}
}
/**
* 只判断Y轴的手势
* @param gapY y轴上面滑动的距离
*/
private void DoOnlyY(float gapY) {
if(gapY >0){ //手指下拉刷新
currentAction = TouchActionType.ACTION_Y_DOWN;
}else{ // 手势上拉加载更多
currentAction = TouchActionType.ACTION_Y_UP;
}
mHandler.sendEmptyMessage(currentAction);
isLocked = true;
}
/**
* 只判断X轴的手势
* @param moveX
*/
private void DoOnlyX(float gapX) {
if(gapX > 0){ //从左往右滑
currentAction = TouchActionType.ACTION_X_RIGHT;
Log.e("右滑", "右滑");
}else{ //从右往左滑
currentAction = TouchActionType.ACTION_X_LEFT;
Log.e("左滑", "左滑");
}
mHandler.sendEmptyMessage(currentAction);
isLocked = true;
}
/**
* 同时判断X轴和Y轴的手势
* @param moveX
* @param moveY
*/
private void DoBothXY(float gapX,float gapY) {
if(Math.abs(gapX) > Math.abs(gapY)){ //如果x轴滑动到距离比较大,则判断为x轴事件
DoOnlyX(gapX);
}else{
DoOnlyY(gapY);
}
}
/**
*
* @param moveX
* @param moveY
*/
private void DoXAndLYAndRY(float gapX,float gapY) {
double middle = screenWidth / 2.0;
if(Math.abs(gapX) > Math.abs(gapY)){ //如果x轴滑动到距离比较大,则判断为x轴事件
DoOnlyX(gapX);
Log.e("X轴动作", "X轴动作");
}else{
if(startX < middle){ //Y轴左屏,
if(gapY >0){ //手指下拉刷新
currentAction = TouchActionType.ACTION_Y_LEFT_DOWN;
Log.e("手指下拉刷新", "左屏");
}else{ // 手势上拉加载更多
currentAction = TouchActionType.ACTION_Y_LEFT_UP;
Log.e("手势上拉加载更多", "左屏");
}
}else{
if(gapY >0){ //手指下拉刷新
currentAction = TouchActionType.ACTION_Y_RIGHT_DOWN;
}else{ // 手势上拉加载更多
currentAction = TouchActionType.ACTION_Y_RIGHT_UP;
}
}
mHandler.sendEmptyMessage(currentAction);
isLocked = true;
}
}
/**
* 获取当前的action是什么
* @return
*/
public int getCurrentAction() {
return currentAction;
}
/**
* 获取当前是否已判定动作
* @return
*/
public boolean isLocked() {
return isLocked;
}
}事件的使用:
只需要几行代码,其中GestureHandler是接受判读手势完成后的消息句柄,而后面那个枚举类型的值则是选择一种要判断的手势的类型,具体参考GestureType 类中的注释:
KindlionOnTouchListener listener = new KindlionOnTouchListener(GestureHandler, GestureType.GESTURE_X_LEFTY_RIGHTY);
view.setOnTouchListener(listener);
Handler GestureHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case TouchActionType.ACTION_TOUCH_DOWN:
player_title.setText("按下");
break;
case TouchActionType.ACTION_TOUCH_UP:
player_title.setText("起来");
player_overlay_info.setVisibility(View.GONE);
break;
case TouchActionType.ACTION_Y_LEFT_DOWN:
player_title.setText("y轴左边下拉");
player_overlay_info.setText("亮度-");
player_overlay_info.setVisibility(View.VISIBLE);
break;
case TouchActionType.ACTION_Y_LEFT_UP:
player_title.setText("y轴左边上拉");
player_overlay_info.setText("亮度+");
player_overlay_info.setVisibility(View.VISIBLE);
break;
case TouchActionType.ACTION_Y_RIGHT_DOWN:
player_title.setText("y轴右边下拉");
player_overlay_info.setText("声音-");
player_overlay_info.setVisibility(View.VISIBLE);
break;
case TouchActionType.ACTION_Y_RIGHT_UP:
player_title.setText("y轴右边上拉");
player_overlay_info.setText("声音+");
player_overlay_info.setVisibility(View.VISIBLE);
break;
case TouchActionType.ACTION_X_LEFT:
player_title.setText("x轴左滑");
player_overlay_info.setText("快退");
player_overlay_info.setVisibility(View.VISIBLE);
break;
case TouchActionType.ACTION_X_RIGHT:
player_title.setText("x轴右滑");
player_overlay_info.setText("快进");
player_overlay_info.setVisibility(View.VISIBLE);
break;
default:
break;
}
};
};
这里面还有一些需要优化的东西,比如在屏幕滑动的时候可能还需要获取当前滑动的距离,并实时的做一些事情,比如播放器中调节音量,调节亮度,调节进度等等都需要显示一个tips来提示当前调节的进度,所以下次要加入的东西应该是move动作的事件处理。
本文继续探讨Android手势封装,重点介绍如何实现手势管理及在ListView等场景中的应用。通过GestureHandler接收手势完成的消息,并利用GestureType进行手势类型判断。在实际使用中,手势可用于播放器的音量、亮度和进度调节,未来计划增加对move事件的处理以显示实时进度提示。
566

被折叠的 条评论
为什么被折叠?



