Search code examples
androidontouchlistenerregion

Regions in Android, basic touch implementing


I found out in one of my earlier questions that setting up specific x,y coordinates as Touch Listeners was too specific and that just one position would be too small to pick up a touch input.

@ligi mentioned Regions in a comment under my question. I looked into it and realised that it's what I need, I just can't find out how to implement one.

Here is the code for a TouchListener for a specific x,y coordinate:

public boolean onTouchEvent(MotionEvent ev) {
    if (!mDragging) {
        return false;
    }

    int x = (int) ev.getX();
    int y = (int) ev.getY();

    if (x == 100 && y == 200) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.e(TAG, "ACTION DOWN");
            break;

        case MotionEvent.ACTION_MOVE:
            Log.e(TAG, "ACTION MOVE");
            break;

        case MotionEvent.ACTION_UP:
            Log.e(TAG, "ACTION UP");
            break;
        }
    }

Does anyone know how to set up a Region instead? Say if a user finger moves into the region area, do something. I can't find any basic implementations anywhere else.

Here's an image if the desc. wasn't clear:


Solution

  • You could do something like this

    public boolean onTouchEvent(MotionEvent ev) {
    
        int x = (int) ev.getX();
        int y = (int) ev.getY();
    
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "ACTION DOWN OR MOVE");
    
                // check if the event is in region 1
                if(x >= "left_x_region1" && x <= "right_x_region1"
                    && y >= "top_x_region1" && y <= "bottom_x_region1")
                    // do something for region1
    
                // check if the event is in region 2
                else if(x >= "left_x_region2" && x <= "right_x_region2"
                    && y >= "top_x_region2" && y <= "bottom_x_region2")
                    // do something for region1
    
                // continue for other cases
                break;
            case MotionEvent.ACTION_UP:
                Log.e(TAG, "ACTION UP");
                break;
        }
    }
    

    Or you could simplify it even further by making a list of what those actual values are, or even better create Rects from those values

    List<Rect> regions = new ArrayList<Rect>();
    regions.add(new Rect("left_x_region1", "top_y_region1", "right_x_region1", "bottom_y_region1");
    regions.add(new Rect("left_x_region2", "top_y_region2", "right_x_region2", "bottom_y_region2");
    // continue for each region
    

    and then check your event in those regions inside your ACTION_DOWN || ACTION_MOVE section of the switch statement

    for(int i = 0; i < regions.size(); i++){
        if(regions.get(i).contains(x, y)){
           // do stuff for region i
           return;
        }
    }
    

    What this does is checks to see if the motion event occurred within the bounds of the region.