-
-
Save billmote/c15a3733f39c5095287f to your computer and use it in GitHub Desktop.
This file contains hidden or 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.graphics.Rect; | |
| import android.view.TouchDelegate; | |
| import android.view.View; | |
| import android.view.ViewTreeObserver.OnGlobalLayoutListener; | |
| import android.widget.CheckBox; | |
| /** | |
| * Enlarges the effective hit target of a checkbox to more closely match the dimensions of the | |
| * provided root view. If the provided root isn't actually an ancestor view of the checkbox, bad | |
| * things will happen. | |
| */ | |
| public class CheckBoxHelper { | |
| public static void enlargeCheckBoxHitTarget(final View rootView, final CheckBox checkBox) { | |
| ViewTreeObserverHelper.notifyWhenMeasured(rootView, new OnGlobalLayoutListener() { | |
| @Override | |
| public void onGlobalLayout() { | |
| Rect origHitRect = new Rect(); | |
| checkBox.getHitRect(origHitRect); | |
| int relativeCheckTop = ViewHelper.getRelativeTop(rootView, checkBox); | |
| int relativeCheckBottom = ViewHelper.getRelativeBottom(rootView, checkBox); | |
| int relativeCheckLeft = ViewHelper.getRelativeLeft(rootView, checkBox); | |
| int additionalTop = relativeCheckTop; | |
| int additionalBottom = rootView.getMeasuredHeight() - relativeCheckBottom; | |
| int additionalLeft = relativeCheckLeft; | |
| int additionalRight = additionalLeft; // Semi-arbitrary, right is same as left | |
| Rect delegateHitRect = new Rect( | |
| origHitRect.left - additionalLeft, | |
| origHitRect.top - additionalTop, | |
| origHitRect.right + additionalLeft + additionalRight, | |
| origHitRect.bottom + additionalTop + additionalBottom); | |
| rootView.setTouchDelegate(new TouchDelegate(delegateHitRect, checkBox)); | |
| } | |
| }); | |
| } | |
| } |
This file contains hidden or 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
| Before (white space around the checkbox is not touchable): | |
| ____________________ | |
| | | | |
| | [.] Lorem ipsum | | |
| |____________________| | |
| After (dots around the checkbox are touchable): | |
| ____________________ | |
| |....... | | |
| |..[.]..Lorem ipsum | | |
| |......._____________| |
This file contains hidden or 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
| View convertView = // for example, something from an adapter | |
| CheckBox checkBox = // a checkbox that exists inside of convertview | |
| CheckBoxHelper.enlargeCheckBoxHitTarget(convertView, checkBox); |
This file contains hidden or 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.view.View; | |
| public class ViewHelper { | |
| /** | |
| * Similar to View.getLeft(), but you specify what parent the value is relative to. If you | |
| * provide a root view that isn't actually an ancestor view, bad things will happen. | |
| */ | |
| public static int getRelativeLeft(View relativeRootView, View view) { | |
| if (view.getParent() == relativeRootView) { | |
| return view.getLeft(); | |
| } else { | |
| return view.getLeft() + getRelativeLeft(relativeRootView, (View) view.getParent()); | |
| } | |
| } | |
| /** | |
| * Similar to View.getTop(), but you specify what parent the value is relative to. If you | |
| * provide a root view that isn't actually an ancestor view, bad things will happen. | |
| */ | |
| public static int getRelativeTop(View relativeRootView, View view) { | |
| if (view.getParent() == relativeRootView) { | |
| return view.getTop(); | |
| } else { | |
| return view.getTop() + getRelativeTop(relativeRootView, (View) view.getParent()); | |
| } | |
| } | |
| /** | |
| * Similar to View.getRight(), but you specify what parent the value is relative to. If you | |
| * provide a root view that isn't actually an ancestor view, bad things will happen. | |
| */ | |
| public static int getRelativeRight(View relativeRootView, View view) { | |
| if (view.getParent() == relativeRootView) { | |
| return view.getRight(); | |
| } else { | |
| return getRelativeRight(relativeRootView, (View) view.getParent()) - view.getRight(); | |
| } | |
| } | |
| /** | |
| * Similar to View.getBottom(), but you specify what parent the value is relative to. If you | |
| * provide a root view that isn't actually an ancestor view, bad things will happen. | |
| */ | |
| public static int getRelativeBottom(View relativeRootView, View view) { | |
| if (view.getParent() == relativeRootView) { | |
| return view.getBottom(); | |
| } else { | |
| return getRelativeBottom(relativeRootView, (View) view.getParent()) - view.getBottom(); | |
| } | |
| } | |
| } |
This file contains hidden or 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.annotation.SuppressLint; | |
| import android.os.Build; | |
| import android.view.View; | |
| import android.view.ViewTreeObserver; | |
| @SuppressLint("NewApi") | |
| public class ViewTreeObserverHelper { | |
| public static void notifyWhenMeasured(final View view, final ViewTreeObserver.OnGlobalLayoutListener listener) { | |
| ViewTreeObserver vto = view.getViewTreeObserver(); | |
| vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { | |
| @Override | |
| public void onGlobalLayout() { | |
| listener.onGlobalLayout(); | |
| // Need to get a fresh ViewTreeObserver | |
| ViewTreeObserver freshVto = view.getViewTreeObserver(); | |
| if (Build.VERSION.SDK_INT < 16) { | |
| deprecatedRemoveOnGlobalLayoutListener(freshVto); | |
| } else { | |
| freshVto.removeOnGlobalLayoutListener(this); | |
| } | |
| } | |
| /** | |
| * Deprecated because it was inconsistently named. | |
| * | |
| * This is in its own method to isolate the scope of the suppressed warning. | |
| */ | |
| @SuppressWarnings("deprecation") | |
| private void deprecatedRemoveOnGlobalLayoutListener(ViewTreeObserver freshVto) { | |
| freshVto.removeGlobalOnLayoutListener(this); | |
| } | |
| }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment