Android change touch area of View by TouchDelegate

Recently while using one application I noticed that application has the pretty small buttons and sometimes it pretty tough to click those views. Ideally, all clickable view should be large enough in UI so that they are easily clickable but still if we have a small view on the screen which are pretty small we can increase the touch area of this views while keeping the size of those views same. I am gonna discuss a couple of different solution which we can use to increase the touchable area of view.

Let’s assume we want to increase the clickable area of the button which is defined in our layout

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/click_me" />

(1) Put this view in another View container like frame layout and add padding to the amount you want to increase the touchable area of view. Then, set the click listener for view group in which we call the “performClick” method on our button. That will increase the touch area of the button. But if you observe right now when you click outside the bound of the button but inside the view group on click is called but the button is not showing it’s pressed state. We can enable that too by adding this attribute in our button
“android:duplicateParentState=”true””

Frame Layout with 20dp padding

(2) Use TouchDelegate: Android provide this class for doing this specific thing. To use this class, we should get current “hit rectangle” of the view. “Hit Rectangle” means the current touchable area of view and then we change the bound of that rectangle based on our need. In my case I am adding touchable are on all sides. Then creating the touch delegate object based on the new rectangle and pass the view whose touchable bound want to change. Then set the newly created touch delegate object to the parent of the view as touch delegate.
Below is the helper method which I created to change the touchable area of any view

private fun changeTouchableAreaOfView(view: View, extraSpace: Int) {
val parent = view.parent as View
Observable.just(parent)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe {
val touchableArea = Rect()
view.getHitRect(touchableArea)
touchableArea.top -= extraSpace
touchableArea.bottom += extraSpace
touchableArea.left -= extraSpace
touchableArea.right += extraSpace
parent.touchDelegate = TouchDelegate(touchableArea, button)
}

/* In case you don't want to use Rx java
parent.post {
val touchableArea = Rect()
button.getHitRect(touchableArea)
touchableArea.top -= extraSpace
touchableArea.bottom += extraSpace
touchableArea.left -= extraSpace
touchableArea.right += extraSpace
parent.touchDelegate = TouchDelegate(touchableArea, button)
}
*/

}

For more info: https://developer.android.com/reference/android/view/TouchDelegate.html

The (retired) Pub(lication) for Android & Tech, focused on Development