Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: How to reduce the clickable area of View?

Tags:

android

I have two images whose transparent area are overlapping with each other. When i am clicking one image , the onclicklistener of another image gets called. Is there anyway to reduce the clickable area of ImageView.

like image 536
Amit Avatar asked Nov 22 '11 10:11

Amit


3 Answers

You create a TouchDelegate :  

final View parent = (View) findViewById(R.id.touch_delegate_root); 
parent.post( new Runnable() {
    // Post in the parent's message queue to make sure the parent
    // lays out its children before we call getHitRect()
    public void run() {
        final Rect rect = new Rect();
        Button delegate = YourActivityClass.this.mButton;
        delegate.getHitRect(rect);
        rect.top -= 20;
        rect.bottom += 12;  // etc 
        parent.setTouchDelegate( new TouchDelegate( rect , delegate));
    }
});

refered from here

like image 83
Reno Avatar answered Nov 02 '22 17:11

Reno


You can solve it using xml only. Just put your image in a frame and place another transparent view that you wire to click events on top of it. Adjust size and position with layout parameters:

<FrameLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content">
 <ImageView android:id="your_view"
  android:clickable="false"
  <!-- your other attributes -->
  <!-- ... -->
  />
  <ImageView android:id="the_clickable_view"
      android:src="@null"
  <!-- set desired size of clickable area -->
  <!-- align it inside a frame using:
  android:gravity and android:margins -->
  />
</FrameLayout>
like image 37
Jarosław Jaryszew Avatar answered Nov 02 '22 17:11

Jarosław Jaryszew


Don't use the OnClickListener, but the OnTouchListener and handle the click area by yourself.

For example by scaling the touch rectangle and translating it to the center of the view. You could also use radius or manual offsets.

imageView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        final Rect rect = new Rect();
        v.getHitRect(rect);

        float scale = 0.5f;

        final float x = event.getX();
        final float y = event.getY();

        final float minX = v.getWidth() * 0.5f * (1.0f - scale);
        final float maxX = v.getWidth() * 0.5f * (1.0f + scale);

        final float minY = v.getHeight() * 0.5f * (1.0f - scale);
        final float maxY = v.getHeight() * 0.5f * (1.0f + scale);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (x > minX && x < maxX && y > minY && y < maxY) {
                    Log.d("TOUCH", String.valueOf(x) + " " + String.valueOf(y));
            }
            break;

        }
        return true;
    }
});
like image 31
lubosz Avatar answered Nov 02 '22 17:11

lubosz