FileDocCategorySizeDatePackage
TouchDelegate.javaAPI DocAndroid 1.5 API5103Wed May 06 22:41:56 BST 2009android.view

TouchDelegate

public class TouchDelegate extends Object
Helper class to handle situations where you want a view to have a larger touch area than its actual view bounds. The view whose touch area is changed is called the delegate view. This class should be used by an ancestor of the delegate. To use a TouchDelegate, first create an instance that specifies the bounds that should be mapped to the delegate and the delegate view itself.

The ancestor should then forward all of its touch events received in its {@link android.view.View#onTouchEvent(MotionEvent)} to {@link #onTouchEvent(MotionEvent)}.

Fields Summary
private android.view.View
mDelegateView
View that should receive forwarded touch events
private android.graphics.Rect
mBounds
Bounds in local coordinates of the containing view that should be mapped to the delegate view. This rect is used for initial hit testing.
private android.graphics.Rect
mSlopBounds
mBounds inflated to include some slop. This rect is to track whether the motion events should be considered to be be within the delegate view.
private boolean
mDelegateTargeted
True if the delegate had been targeted on a down event (intersected mBounds).
public static final int
ABOVE
The touchable region of the View extends above its actual extent.
public static final int
BELOW
The touchable region of the View extends below its actual extent.
public static final int
TO_LEFT
The touchable region of the View extends to the left of its actual extent.
public static final int
TO_RIGHT
The touchable region of the View extends to the right of its actual extent.
private int
mSlop
Constructors Summary
public TouchDelegate(android.graphics.Rect bounds, android.view.View delegateView)
Constructor

param
bounds Bounds in local coordinates of the containing view that should be mapped to the delegate view
param
delegateView The view that should receive motion events


                                             
         
        mBounds = bounds;

        mSlop = ViewConfiguration.get(delegateView.getContext()).getScaledTouchSlop();
        mSlopBounds = new Rect(bounds);
        mSlopBounds.inset(-mSlop, -mSlop);
        mDelegateView = delegateView;
    
Methods Summary
public booleanonTouchEvent(android.view.MotionEvent event)
Will forward touch events to the delegate view if the event is within the bounds specified in the constructor.

param
event The touch event to forward
return
True if the event was forwarded to the delegate, false otherwise.

        int x = (int)event.getX();
        int y = (int)event.getY();
        boolean sendToDelegate = false;
        boolean hit = true;
        boolean handled = false;

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Rect bounds = mBounds;

            if (bounds.contains(x, y)) {
                mDelegateTargeted = true;
                sendToDelegate = true;
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_MOVE:
            sendToDelegate = mDelegateTargeted;
            if (sendToDelegate) {
                Rect slopBounds = mSlopBounds;
                if (!slopBounds.contains(x, y)) {
                    hit = false;
                }
            }
            break;
        case MotionEvent.ACTION_CANCEL:
            sendToDelegate = mDelegateTargeted;
            mDelegateTargeted = false;
            break;
        }
        if (sendToDelegate) {
            final View delegateView = mDelegateView;
            
            if (hit) {
                // Offset event coordinates to be inside the target view
                event.setLocation(delegateView.getWidth() / 2, delegateView.getHeight() / 2);
            } else {
                // Offset event coordinates to be outside the target view (in case it does
                // something like tracking pressed state)
                int slop = mSlop;
                event.setLocation(-(slop * 2), -(slop * 2));
            }
            handled = delegateView.dispatchTouchEvent(event);
        }
        return handled;