Sandeep
Sandeep

Reputation: 3344

Activity's onTouchEvent() is not being called while clicking on Button

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.

Upvotes: 11

Views: 26644

Answers (5)

Sandeep
Sandeep

Reputation: 3344

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.

Upvotes: 19

Antonio Moreno Borras
Antonio Moreno Borras

Reputation: 81

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
             }
    }
}

Upvotes: 0

Ranjit
Ranjit

Reputation: 209

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);

Upvotes: 1

Divyang Metaliya
Divyang Metaliya

Reputation: 1918

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;
        }
    });

Upvotes: 0

Manish Srivastava
Manish Srivastava

Reputation: 1659

 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" />

Upvotes: 0

Related Questions