Siddhpura Amit
Siddhpura Amit

Reputation: 15078

onTouchListener in Android will detect touch on all parent view

I have

 RelativeLayout

       A---BIG IMAGE
       B---MEDIUM IMAGE
       C---SMALL IMAGE

The picture is looking like this

enter image description here

I have used below java code

@Override
    public boolean onTouch(View v, MotionEvent event) {

                switch (v.getId()) {
                // LEFT
                case R.id.tblLOne:
                    System.out.println("IMG_L_A");
                    playBeep(TABLA_L_BIG);
                    changeLeftDrum();
                    break;
                case R.id.tblLTwo:
                    System.out.println("IMG_L_B");
                    playBeep(TABLA_L_MID);
                    changeLeftDrum();
                    break;
                case R.id.tblLThree:
                    System.out.println("IMG_L_C");
                    playBeep(TABLA_L_SMALL);
                    changeLeftDrum();
                    break;
                return false;
                }
                return true;

    }

Problem is that whenever I click on small (BLACK) Image

I got following output

IMG_L_A
IMG_L_B
IMG_L_C

Whenever I click on Middle Image I got

IMG_L_A
IMG_L_B

On OuterImage big image

IMG_L_A

Why I am getting it's all behind ImageView's OnTouch Method

It is working perfect with onClick but not with OnTouch

Upvotes: 4

Views: 364

Answers (2)

Shivam Verma
Shivam Verma

Reputation: 8023

It's because the views are stacked on top of each other.

The important point here is to know the importance of the Boolean flag that you return from your onTouchListener. The boolean flag tells android if the event was consumed or not.

Suppose, you touch tblRthree, the case R.id.tblLThree executes, but then since you return false, it appears to android that the event was not consumed and this event bubbles up to the tblRTwo view which is just behind tblRthree view, which executes the same listener for the case R.id.tblLTwo but then again you return false so, it bubbles up to view tblROne and all three cases execute.

You should return true whenever you consume the event, and false when you don't.

Upvotes: 5

Mehul Joisar
Mehul Joisar

Reputation: 15358

onTouch method will be called in multiple events, all you need is to check whether it is MotionEvent.ACTION_DOWN or not.

So, it will look something like this:

@Override
public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction()!=MotionEvent.ACTION_DOWN)
            {
             return false;//we are not going to handle it
            }  

            switch (v.getId()) {
            // LEFT
            case R.id.tblLOne:
                System.out.println("IMG_L_A");
                playBeep(TABLA_L_BIG);
                changeLeftDrum();
                break;
            case R.id.tblLTwo:
                System.out.println("IMG_L_B");
                playBeep(TABLA_L_MID);
                changeLeftDrum();
                break;
            case R.id.tblLThree:
                System.out.println("IMG_L_C");
                playBeep(TABLA_L_SMALL);
                changeLeftDrum();
                break;
            }
            return true;//we have handled it
}

Upvotes: 0

Related Questions