首页 > 代码库 > Android项目---TouchListener
Android项目---TouchListener
public static interface
View.OnTouchListener
android.view.View.OnTouchListener |
Known Indirect Subclasses AutoScrollHelper, ListViewAutoScrollHelper, ZoomButtonsController |
Class Overview
Interface definition for a callback to be invoked when a touch event is dispatched to this view. The callback will be invoked before the touch event is given to the view.
Summary
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
abstract boolean | onTouch(View v, MotionEvent event) Called when a touch event is dispatched to a view. |
用到这个类,一般就是在Android项目中,获取手点击屏幕的焦点。
如果实在控件上操作的话,一般将TouchListener事件单独提出来,写成一个工具类。
一、定义TouchListener工具类
public class TouchListener implements OnTouchListener { Context context; float oldDist; float newDist; float oldY; float newY; List<Float> list = new ArrayList<Float>(); boolean on_off; public TouchListener(Context context) { this.context = context; } @Override public boolean onTouch(View v, MotionEvent event) { float f2 = event.getRawX(); list.add(f2); oldDist = list.get(0);// 存集合里 又因为onTouch方法会不断会掉 这个值会不断加入集合中 switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: System.out.println("DOWN"); oldY = event.getY(); break; case MotionEvent.ACTION_UP: System.out.println("UP"); newDist = event.getRawX(); if (oldDist < 100 && newDist - oldDist > 200) { Intent intent = new Intent(); intent.setAction("open"); context.sendBroadcast(intent); HomeActivity.isopen = true; } if (newDist - oldDist < -200 || (newDist - oldDist > 0 && newDist - oldDist < 200 && oldDist < 100)) { Intent intent = new Intent(); intent.setAction("back"); context.sendBroadcast(intent); } if (newDist - oldDist < 0 && newDist - oldDist > -200 && HomeActivity.isopen) { Intent intent = new Intent(); intent.setAction("open"); context.sendBroadcast(intent); HomeActivity.isopen = true; } else { list = new ArrayList<Float>(); newY = event.getY(); if (Math.abs(newY - oldY) < 40 && Math.abs(newDist - oldDist) > 40) {return true; } else {return false; } } break; case MotionEvent.ACTION_MOVE: System.out.println("MOVE"); newDist = event.getRawX(); float distance = newDist - oldDist; Intent intent = new Intent(); intent.putExtra("distance", distance); intent.putExtra("old", oldDist); intent.setAction("move"); context.sendBroadcast(intent); Log.i("info", "MOVE"); break; } return true; } }
注:一定要给每个case写break。。。
ACTION_MASK在Android中是应用于多点触摸操作,字面上的意思大概是动作掩码的意思吧。
在onTouchEvent(MotionEvent event)中
使用switch (event.getAction())可以处理ACTION_DOWN和ACTION_UP事件
使用switch (event.getAction() & MotionEvent.ACTION_MASK)就可以处理处理多点触摸的ACTION_POINTER_DOWN和ACTION_POINTER_UP事件。
ACTION_DOWN和ACTION_UP就是单点触摸屏幕,按下去和放开的操作;
ACTION_POINTER_DOWN和ACTION_POINTER_UP就是多点触摸屏幕,当有一只手指按下去的时候,另一只手指按下和放开的动作捕捉;
ACTION_MOVE就是手指在屏幕上移动的操作;
TouchListener中有一个问题,在重写onTouch方法的时候,返回值false和true的不同。
如果是false,则出了按钮控件会正常显示down,up,move的值,其他控件都只能显示down的事件
如果是true,则就会不断的取值。
event.getX();//指的是控件的x坐标
event.getRawX();//指的是屏幕的X坐标
二、接收广播
BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("open")) { new AsyncMove2().execute(); } if (intent.getAction().equals("back")) { isopen = false; new AsyncMove2().execute(); } if (intent.getAction().equals("move")) { float f = intent.getFloatExtra("distance", 0); float old = intent.getFloatExtra("old", 0); LinearLayout.LayoutParams lp = (LayoutParams) left_menu .getLayoutParams(); if (isopen && f < 0) { lp.leftMargin = (int) f; } else if (!isopen && f > 0 && old < 100) { lp.leftMargin = (int) (-left_menu.getWidth() + f); } left_menu.setLayoutParams(lp); } } };
三、注册广播
IntentFilter inf = new IntentFilter(); inf.addAction("open"); inf.addAction("back"); inf.addAction("move"); registerReceiver(receiver, inf);
关于onTouch事件的算法思想:
获取动作 多点触控
如果是按下
得到按下时控件的Y轴值
如果是抬起
获取手指抬起时获得的屏幕新的X的值
如果手指按下的位置靠近屏幕左边100像素内,并且新位置的值减去旧位置的值大于200(从左向右滑动)
打开菜单栏(向Activity中发送打开广播)
如果新位置值减去旧位置值小于200(从右向左滑动)或者<新旧位置值差值大于0 并且新减旧小于200(从左向右滑动距离太短)并且是在距离屏幕100像素内>
关闭菜单栏(向Activity中发送关闭广播)
如果现在菜单是打开着的并且是从右向左滑动 且滑动距离很短(小于200) 则将菜单重新弹出
打开菜单栏
否则如果控件Y轴的变化大于50就认为他是要上下滑动listview不去执行左右开关操作
如果手势是弧形 且弧形平缓就理解为是左右滑动
打开菜单
如果手势是弧形 且弧形陡峭就理解为是上下滑动 不在执行打开关闭菜单操作 认为用户是在滑动listview
关闭菜单
如果是移动
获取屏幕的x值
获取移动的距离
发送广播