Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: View.setClickable consumes click event

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) {}
     });
}
like image 236
Christopher Masser Avatar asked Apr 14 '12 11:04

Christopher Masser


Video Answer


1 Answers

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.

like image 107
Michal Vician Avatar answered Oct 02 '22 01:10

Michal Vician