Created
November 3, 2014 08:48
-
-
Save rcgroot/cf30c81e5492a8afd88b to your computer and use it in GitHub Desktop.
Enlarge the touch targets of small views in Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.graphics.Rect; | |
import android.view.TouchDelegate; | |
import android.view.View; | |
/** | |
* <p> | |
* Ensures minimum hitbox size of small touch targets. For example: | |
* <p> | |
* <code> | |
* TouchDelegateAdjustment.adjustTouchSize(getActivity(), smallView);<br> | |
* </code> | |
* | |
* @see #adjustTouchSize(Context, View) | |
* @version 2 | |
*/ | |
public class TouchDelegateAdjustment implements Runnable | |
{ | |
// 50 dp is about 9 mm in on screen size | |
final private static int MIN_TOUCH_WIDTH_DP = 50; | |
final private static int MIN_TOUCH_HEIGHT_DP = 50; | |
private View delegate; | |
private int topPadding; | |
private int bottomPadding; | |
private int leftPadding; | |
private int rightPadding; | |
/** | |
* Constructor: Increase the hitbox to minimum of about 9mm by 9mm size with the delegate in the middle. | |
* | |
* @param ctx The context from which to retrieve the screen density information | |
* @param smallView The view on which a alter the hitbox | |
*/ | |
public TouchDelegateAdjustment(Context ctx, View smallView) | |
{ | |
this(ctx, smallView, MIN_TOUCH_WIDTH_DP, MIN_TOUCH_HEIGHT_DP); | |
} | |
/** | |
* Constructor: Increase the hitbox to minimum of about 9mm by 9mm size with the delegate in the middle. | |
* | |
* @param ctx The context from which to retrieve the screen density information | |
* @param smallView The view one which a alter the hitbox | |
* @param minWidth Minimum width of the hit rects in dip | |
* @param minHeight Minimum height of the hit rects in dip | |
*/ | |
public TouchDelegateAdjustment(Context ctx, View smallView, int minWdith, int minHeight) | |
{ | |
this.delegate = smallView; | |
int minimumTouchWidth = (int) (minWdith * ctx.getResources().getDisplayMetrics().density + 0.5f); | |
int minimumTouchHeight = (int) (minHeight * ctx.getResources().getDisplayMetrics().density + 0.5f); | |
Rect touchRect = new Rect(); | |
smallView.getHitRect(touchRect); | |
int heightPadding = (minimumTouchHeight - touchRect.height()) / 2; | |
int widthPadding = (minimumTouchWidth - touchRect.width()) / 2; | |
this.topPadding = heightPadding; | |
this.bottomPadding = heightPadding; | |
this.leftPadding = widthPadding; | |
this.rightPadding = widthPadding; | |
} | |
/** | |
* Posted in the parent's message queue to make sure the parent lays out its children before we call getHitRect() | |
*/ | |
public void run() | |
{ | |
View parent; | |
try | |
{ | |
parent = (View) delegate.getParent(); | |
} | |
catch (ClassCastException e) | |
{ | |
throw new IllegalArgumentException("Only Views with a View as parent can have touch area enlarged", e); | |
} | |
// Construct a new Rectangle and let the Delegate set its values | |
Rect touchRect = new Rect(); | |
delegate.getHitRect(touchRect); | |
// Modify the dimensions of the Rectangle | |
// Padding values below zero are replaced by zeros | |
touchRect.top -= Math.max(0, topPadding); | |
touchRect.bottom += Math.max(0, bottomPadding); | |
touchRect.left -= Math.max(0, leftPadding); | |
touchRect.right += Math.max(0, rightPadding); | |
// Now we are going to construct the TouchDelegate | |
TouchDelegate touchDelegate = new TouchDelegate(touchRect, delegate); | |
// And set it on the parent | |
parent.setTouchDelegate(touchDelegate); | |
} | |
/** | |
* Convenience method to initialize, connect and run the enlarger | |
* | |
* @param ctx The context from which to retrieve the screen density information | |
* @param smallView The view on which a alter the hitbox | |
* @see #TouchDelegateAdjustment(Context, View) | |
*/ | |
static void adjustTouchSize(Context ctx, View smallView) | |
{ | |
View parent = (View) smallView.getParent(); | |
parent.post(new TouchDelegateAdjustment(ctx, smallView)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment