2011-11-23

Drawable#getTransparentRegion on Android (in case of BitmapDrawable)

Drawable#getTransparentRegion is not implemented at all in Android SDK. So we have to override and implement all by my self.

Here is an altenative answer with overriding Button class to avoid firing onClick method when tap transparent regions of a background image.

Strategy Overview


The code of TransparentImageButton


class TransparentImageButton extends Button{

 private View mCovering;

 public void setCoveringView(View cListener){
  mCovering = cListener;
 }

 /**
  * - Call onClick indirectly(super.onTouchEvent()->(in super class) performClick())
  * - In some cases, this may throw StackOverflowException.
  */
 @Override
 public boolean onTouchEvent(MotionEvent cEvent){
  switch(cEvent.getAction()){
   case MotionEvent.ACTION_DOWN:{
    // obtain the current background drawable
    Drawable cCurrentDrawable = super.getBackground().getCurrent();
    if(cCurrentDrawable instanceof BitmapDrawable){
     
     Bitmap cBmp = null;
     
     if(cCurrentDrawable instanceof BitmapDrawable){
      // cast the BitmapDrawable data into cBmp
      cBmp = ((BitmapDrawable) cCurrentDrawable).getBitmap();
     }

     // check whether the dot in drawable at the touched point is transparent or not
     if(null != cBmp && cBmp.getPixel((int)cEvent.getX(), (int)cEvent.getY()) != 0){
      // if not
      mIsPreviousTarget = true;
      return super.onTouchEvent(cEvent);
     }else{
      // if transparent
      mIsPreviousTarget = false;
      if(null != mCovering){
       return mCovering.onTouchEvent(cEvent);
      }
     }
    }
    break;
   }
   default:
    if(mIsPreviousTarget){
     super.onTouchEvent(cEvent);
    }else{
     if(null != mCovering){
      return mCovering.onTouchEvent(cEvent);
     }
    }
    break;
  }
  return false;
 }
 private boolean mIsPreviousTarget = false;

}