How to get a continuous Touch Event?

后端 未结 7 1578
死守一世寂寞
死守一世寂寞 2021-01-17 14:01

My class extends View and I need to get continuous touch events on it.

If I use:

public boolean onTouchEvent(MotionEvent me) {

    if(me.getAction()         


        
相关标签:
7条回答
  • 2021-01-17 14:14

    Use if(me.getAction() == MotionEvent.ACTION_MOVE). It's impossible to keep a finger 100% completely still on the screen so Action_Move will get called every time the finger moves, even if it's only a pixel or two.

    You could also listen for me.getAction() == MotionEvent.ACTION_UP - until that happens, the user must still have their finger on the screen.

    0 讨论(0)
  • 2021-01-17 14:14

    Try this. It works to me:

    public static OnTouchListener loadContainerOnTouchListener() {
        OnTouchListener listener = new OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            LinearLayout layout = (LinearLayout)v;
            for(int i =0; i< layout.getChildCount(); i++)
            {
                View view = layout.getChildAt(i);
                Rect outRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
                if(outRect.contains((int)event.getX(), (int)event.getY()))
                {
                    Log.d(this.getClass().getName(), String.format("Over view.id[%d]", view.getId()));
                }
            }
    
        }
    

    Remember: the listener you´ll set must be a container layout (Grid, Relative, Linear).

    LinearLayout layout = findViewById(R.id.yourlayoutid);
    layout.setOnTouchListener(HelperClass.loadContainerOnTouchListener());
    
    0 讨论(0)
  • 2021-01-17 14:17

    All these answer are partially correct but they do not resolve in the right way the problem.

    First of all, for everyone out there that decide to track when the event is ACTION_MOVE. Well that works only guess when? When user move his finger, so could if you decide to implement a custom thumb control is okay but for a normal custom button that's not the case.

    Second, using a flag inside ACTION_DOWN and check it in ACTION_UP seems the logic way to do it, but as Clusterfux find out if you implement a while(!up_flag) logic you get stuck into troubles ;)

    So the proper way to do it is mentioned here:

    Continuous "Action_DOWN" in Android

    Just keep in mind that if the logic you're going to write during the continuous press has to modify the UI in some way, you have to do it from the main thread in all the other cases it's better use another thread.

    0 讨论(0)
  • 2021-01-17 14:20

    You need to set this properties for the element android:focusable="true" android:clickable="true" if not, just produce the down action.

    0 讨论(0)
  • 2021-01-17 14:28

    I was making a game with a custom view used as a thumb control. . . here is what I did

    float x = 0, y = 0;
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        x = event.getX();
        y = event.getY();
    
        // handle touch events with 
        switch( event.getActionMasked() ) {
            case MotionEvent.ACTION_DOWN :
                if(cont)
                {
                    // remove any previous callbacks
                    removeCallbacks(contin);
    
                    // post new runnable
                    postDelayed(contin, 10);
                }
                invalidate();
                return true;
            case MotionEvent.ACTION_MOVE :
                if(!cont && thumbing != null)
                {
                    //  do non-continuous operations here
                }
                invalidate();       
                return true;
            case MotionEvent.ACTION_UP :
    
                // set runnable condition to false
                x = 0;
    
                // remove the callbacks to the thread
                removeCallbacks(contin);
                invalidate();
                return true;
            default :
                return super.onTouchEvent(event);
        }
    }
    
    public boolean cont = false;
    
    // sets input to continuous
    public void set_continuous(boolean b) { cont = b; }
    
    
    public Runnable contin = new Runnable()
    {
    
        @Override
        public void run() {
            if(x != 0)
            {
                //  do continuous operations here
                postDelayed(this, 10);
            }
        }
    
    };
    

    A quick note however, make sure in your main activity that is calling this view removes the callbacks manually via the onPause method as follows

    @Override
    protected void onPause() {
        if(left.cont) left.removeCallbacks(left.contin);
        if(right.cont) right.removeCallbacks(left.contin); 
        super.onPause();
    }
    

    That way if you pause and come back touch events aren't being handled twice and the view is free from it's thread's overhead.

    ** tested on Samsung Galaxy S3 with hardware acceleration on **

    0 讨论(0)
  • 2021-01-17 14:33

    Her is the simple code snippet which shows that how you can handle the continues touch event. When you touch the device and hold the touch and move your finder, the Touch Move action performed.

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        if(isTsunami){
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Write your code to perform an action on down
                break;
            case MotionEvent.ACTION_MOVE:
                // Write your code to perform an action on contineus touch move
                break;
            case MotionEvent.ACTION_UP:
                // Write your code to perform an action on touch up
                break;
        }
        }
        return true;
    }
    
    0 讨论(0)
提交回复
热议问题