0

I'm using an on touch listener to display and hide some volume controls, on ACTION_DOWN the controls are displayed and on ACTION_UP they are hidden. I want to be able to touch the controls without lifting my finger, I tried using the ACTION_MOVE motion and was unable to get it to work as the event is never triggered. I thought about drag event but I am unsure if it would be appropriate for this.

public boolean onTouch(View v, MotionEvent e)
{
    if(v == audioControls)
    {
        if(e.getAction() == MotionEvent.ACTION_DOWN)
            showVolumeControls();
        else if(e.getAction() == MotionEvent.ACTION_UP)
            hideVolumeControls();

    }


    else if(e.getAction() == MotionEvent.ACTION_MOVE)
    {
        if(v == mute)
        //Do stuff with this volume control
    }

    return true;
}

@Demand answer, read my comment - here is the code:

public boolean onTouch(View v, MotionEvent e)
{
if(v == mute && e.getAction() == MotionEvent.ACTION_MOVE)
{
Toast.makeText(getApplicationContext(), "Muted.", Toast.LENGTH_SHORT).show();
hideVolumeControls();
return true;
}
else
return false;
}
jn025
  • 2,755
  • 6
  • 38
  • 73

1 Answers1

0

So, you need to uderstand how android touch events work. If you touch down on View1, set onTouchListener for that view and return true for that event - other view will never get motion events from same chain.

For you it's mean that if you touch down on "audioControls" then no other views can catch motion events until you release your finger.

You can return false in your onTouch method. In this case parentView for audioControls will also catch all motionEvents. But views, which is not parent for audioControls in the view hierarchy will not catch motionEvent.

You need to catch all motion events in the container for your views and dispatch them for your self. This is the only way to catch motionEvents from one chain in defferent views.

UPDATE: I will try to explain a little bit more. Imagine you have layout like this:

<LinearLayout id="@+id/container">
  <View id="@+id/view1"/>
  <View id="@+id/view2"/>
</LinearLayout>

And you want to touch down on view1 and move your finger to view2. Android touch event flow can't do this. Only one view can catch whole event chain. So you need to add onTouchListener to your container and do something like this.

public boolean onTouch(MotionEvent event) {
  float x = event.getX();
  float y = event.getY();
  for (int i = 0; i<container.getChildCount(); i++) {
    View child = container.getChildAt(i);
    if (x>child.getLeft() && x < child.getRight() && y < child.getBottom() && y > child.getTop()) {
      /*do whatever you want with this view. Child will be view1 or view2, depends on coords;*/
      break;
    }
  }
}

Please note, I wrote this code right there and could make some mistake. I've tried to show the idea.

Alexander Mikhaylov
  • 1,790
  • 1
  • 13
  • 23
  • Could you give an example? I tried this with my action_move on a single view and tried to dragging randomly around the screen (not lifting up) and then moving over the view to see if it fired the event and it didn't. I put the code in my edit – jn025 Jan 21 '15 at 10:09