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;
}

hai,
ReplyDeleteI also got surprised with getTransparentRegion() not being implemented at all, in one of my apps..I have to get the transparent region of a drawable..Is there any other way for this?
thanx
@Bhaskar teja
ReplyDeleteAfter I tried more, I found the following code seem to be more general.
// Generate a bitmap as the base of drawing.
// The constant of 3rd arguments must be contains A(alpha channel)
// (getBottom() etc.. are the method of Button class)
cBmp = Bitmap.createBitmap(
getBottom() - getTop(), getRight() - getLeft(),
Bitmap.Config.ARGB_4444
);
// Draw a drawable on the bitmap.
cDrawable.draw(new Canvas(cBmp));
// Check whether an arbitrary position is transparent or not.
// Specify the check position in first(X) and second(Y) arguments of Bitmap#getPixel
if(null != cBmp &&
(cEvent.getY() < cBmp.getHeight() && cEvent.getX() < cBmp.getWidth()) &&
cBmp.getPixel((int)cEvent.getX(), (int)cEvent.getY()) != 0)
{
// If the checked position is transparent
}
It worked fine for me with even 9-patch drawable.
I think the above code works in class methods extended from Drawable.
In Drawable, it is getBounds().height() that nealy equals to getBottom() - getTop().