Android: View.setClickable consumes click event
Asked Answered
W

2

7

I have a custom Gallery view for horizontal scrolling and several child views that all should be clickable.

Setting childview.setOnClickListener() doesn't work since it always consumes the touch event.

Therefore, I used childview.setOnTouchListener() and let its onTouch method return false, so that the Gallery becomes scrollable.

This is all fine.

The problem is now, that the onTouch method of the childView only fires the ACTION_DOWN event. It doesn't pass on the MotionEvent ACTION_UP unless I make the View clickable by setting childview.setClickable(). However, setting the View clickable itself seems to consume the onTouch event so that the gallery View becomes unscrollable.

Seems like I'm going in a circle here. I'd be grateful for any help.

Here's my code

Gallery View:

public class myGallery extends Gallery {

    public myGallery(Context ctx, AttributeSet attrSet) {
        super(ctx, attrSet);
        // TODO Auto-generated constructor stub
    }

    private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2){ 
           return e2.getX() > e1.getX(); 
        }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
      int kEvent;
      if(isScrollingLeft(e1, e2)){ //Check if scrolling left
        kEvent = KeyEvent.KEYCODE_DPAD_LEFT;
      }else{ //Otherwise scrolling right
        kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;
      }
      onKeyDown(kEvent, null);
      return true;  
    }
}

in my Activity:

gallery.setOnItemSelectedListener(new OnItemSelectedListener(){
     public void onItemSelected(AdapterView<?> parent, View view,
                    int position, long id) {


         //  childView.setClickable(true);   // can't use this
                                             // click event would get consumed
                                            // and gallery would not scroll 

         // therefore, I can only use the ACTION_DOWN event below:

         childView.setOnTouchListener(new OnTouchListener() {
              public boolean onTouch(View v, MotionEvent event) {

              switch (event.getAction()) {
                  case MotionEvent.ACTION_DOWN:
                       //doStuff();
              }

              return false;
              }
         });
    }

    public void onNothingSelected(AdapterView<?> arg0) {}
     });
}
Westward answered 14/4, 2012 at 11:44 Comment(1)
did you get the answer in the second half.Hipparchus
G
5

If I were you, I would try to override ViewGroup.onInterceptTouchEvent(...) method instead of setting OnTouchListener. This way you should be able to intercept on touch events without actually consuming them.

Check out javadoc.

Googolplex answered 2/6, 2013 at 20:11 Comment(0)
N
0

OnTouch needs to return true to indicate you want the rest of the events. Here is an execerpt:

•onTouch() - This returns a boolean to indicate whether your listener consumes this event. The important thing is that this event can have multiple actions that follow each other. So, if you return false when the down action event is received, you indicate that you have not consumed the event and are also not interested in subsequent actions from this event. Thus, you will not be called for any other actions within the event, such as a finger gesture, or the eventual up action event.

From the android dev guid

Nikaniki answered 14/4, 2012 at 12:1 Comment(3)
thanks, I understand. The issue is, if I set onTouch() to return true, then the touch event becomes consumed and the parent view (the Gallery) is not receiving the event any longer, i.e. the gallery becomes unscrollable.Westward
Check out the second half of this section. I think you will find what you need: [developer.android.com/guide/topics/ui/…Nikaniki
I tried finding the answer in second half but couldn't , do you have any quick fix.Hipparchus

© 2022 - 2024 — McMap. All rights reserved.