11

I want to do some B.logic in Activity.onTouchEvent() method. It is working fine for TextView and other non clickable views. However, it is not getting called uponclicking of Button. But I need that too.

Here is the code.

public class MainActivity extends Activity {
    private static final String TAG = MainActivity.class.getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "Oh shit!! click performed... :(", Toast.LENGTH_LONG).show();

            }
        });



    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "ssssssssssssssssssssssss:touch");
        return super.onTouchEvent(event);
    }

    public boolean dispatchTouchEvent(MotionEvent event) {
        int eventaction=event.getAction();

        switch(eventaction) {
        case MotionEvent.ACTION_MOVE:
            break;
        default:
            break;
        }

        return super.dispatchTouchEvent(event);
    }

}

Please help me to sort out from this.

Ameer Moaaviah
  • 1,530
  • 12
  • 27
Noundla Sandeep
  • 3,334
  • 5
  • 29
  • 56
  • 4
    Per the docs, Activity.onTouchEvent() is only called "when a touch screen event was not handled by any of the views under it". Since your button consumes/handles the touch event, the activity is not receiving the call. The TextViews are not consuming the click event. What you're observing would be the expected behavior. – greg7gkb Jul 18 '14 at 02:25
  • I added the solution below by handling Activity.dispatchTouchEvent() method. – Noundla Sandeep Apr 07 '16 at 07:26

5 Answers5

19

I have used dispatchTouchEvent(MotionEvent ev) as required. Here is the solution.

private boolean isInSideClicked = false;
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        View content = findViewById(R.id.textView1);
        int[] contentLocation = new int[2];
        content.getLocationOnScreen(contentLocation);
        Rect rect = new Rect(contentLocation[0], 
                             contentLocation[1], 
                             contentLocation[0] + content.getWidth(), 
                             contentLocation[1] + content.getHeight());
        
        View frame = findViewById(R.id.editText1);
        int[] frameLocation = new int[2];
        frame.getLocationOnScreen(frameLocation);
        Rect framerect = new Rect(frameLocation[0], 
                                  frameLocation[1], 
                                  frameLocation[0] + frame.getWidth(), 
                                  frameLocation[1] + frame.getHeight());
        Log.d(TAG, "rect:  "+rect.bottom+" , "+rect.top+" , "+rect.left+" , "+rect.right);
        Log.d(TAG, "FrameRect:  "+framerect.bottom+" , "+framerect.top+" , "+framerect.left+" , "+framerect.right);
        Log.d(TAG, "x: "+event.getX()+"  y: "+event.getY());
        
        if ((rect.contains((int)event.getX(), (int)event.getY()) || framerect.contains((int)event.getX(), (int)event.getY()) ) ) {
            isInSideClicked = true;
        }
        if (isInSideClicked){
            return super.dispatchTouchEvent(event); 
        } else {
            return true;
        }
    } else if (event.getAction() == MotionEvent.ACTION_UP && isInSideClicked) {
        isInSideClicked = false;
        return super.dispatchTouchEvent(event);
    } else if (event.getAction() == MotionEvent.ACTION_MOVE && isInSideClicked) {
        return super.dispatchTouchEvent(event);
    } else {
        isInSideClicked = false;
        return true; 
    }
}

Below is the hierarchy on how the touch event is processed by OS level.

Activity.dispatchTouchEvent()
ViewGroup.dispatchTouchEvent()
View.dispatchTouchEvent()
View.onTouchEvent()
ViewGroup.onTouchEvent()
Activity.onTouchEvent()

With this I have restricted the touch events of the views which are not in required layouts/views.

Noundla Sandeep
  • 3,334
  • 5
  • 29
  • 56
1

Where you have registering the touchListener for the button. You have only implemented the clickListener for the button. To invoke the onTouchEvent() for button,you have to Register the button as: button.setOnTouchListener(this);

Ranjit
  • 209
  • 5
  • 12
0
 Please add below given 2 line in your xml hope it will help you its working fine for me.

    **android:focusable="false"
    android:focusableInTouchMode="false"**


     <Button
            android:id="@+id/button2"
            android:layout_width="80dp"
            android:layout_height="40dp"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/button1"
            android:layout_marginTop="3dp"
            android:background="#FFFFFF"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:text="Delete"
            android:textColor="#0099CC" />
Manish Srivastava
  • 1,649
  • 2
  • 15
  • 23
0

Please add below code in your onCreate method.

in this you can get down, move or up event of Button.

Write your logic when Button up event call.

findViewById(R.id.btn).setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Toast.makeText(Main.this,
                        "Oh shit!! click down performed... :(",
                        Toast.LENGTH_LONG).show();
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                Toast.makeText(Main.this,
                        "Oh shit!! click up performed... :(",
                        Toast.LENGTH_LONG).show();
                break;
            default:
                break;
            }
            return true;
        }
    });
Divyang Metaliya
  • 1,908
  • 1
  • 12
  • 14
0

I had the same problem. It is very easy to solve, without removing your:

@Override
public boolean onTouchEvent(MotionEvent event) {
    Log.d(TAG, "ssssssssssssssssssssssss:touch");
    return super.onTouchEvent(event);
};

add to the button:

button.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //YOUR CODE HERE
        if(v==button){
           //Your button has been pressed
        }
        else {  
          //Other View element has been pressed
             }
    }
}
Michal
  • 3,584
  • 9
  • 47
  • 74