首页 > 代码库 > 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值
获取移动的距离
发送广播