Last active
November 1, 2016 07:28
-
-
Save dominicthomas/258310a2ab1bc4e976d9 to your computer and use it in GitHub Desktop.
A lovely android view touch area extender builder class. Made to provide a larger touch area to views that aren't standard clickable android view widgets. Works well on things like a small bit of text or a little drop down arrow. The code here is from a project that uses retrolamda and google's guava library for preconditions and optionals.
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 com.google.common.base.Optional; | |
import com.google.common.base.Preconditions; | |
/** | |
* Utility used to extend the touchable area around a view in a viewgroup | |
* Usage: TouchAreaExtender.Builder.with(mReJamCaptionInput) | |
* .parentView(view.findViewById(R.id.rejam_dialog_root_view)).top(100).bottom(100).build(); | |
*/ | |
public class TouchAreaExtender { | |
private TouchAreaExtender(final Builder builder) { | |
final View viewToExtend = builder.mViewToExtend; | |
final View parentView = builder.mParentView; | |
Preconditions.checkNotNull(parentView, "Cannot do this without a parent view."); | |
parentView.post(() -> { | |
// Setup hit rect | |
final Rect delegateArea = new Rect(); | |
final View delegate = viewToExtend; | |
delegate.getHitRect(delegateArea); | |
// Set the direction area pixel values | |
delegateArea.top -= builder.mAll > 0 ? builder.mAll : builder.mTop; | |
delegateArea.bottom += builder.mAll > 0 ? builder.mAll : builder.mBottom; | |
delegateArea.left -= builder.mAll > 0 ? builder.mAll : builder.mLeft; | |
delegateArea.right += builder.mAll > 0 ? builder.mAll : builder.mRight; | |
// Set click listener if it exists | |
if (builder.mViewClickListener.isPresent()) { | |
viewToExtend.setOnClickListener(builder.mViewClickListener.get()); | |
} | |
// Create touch delegate | |
final TouchDelegate expandedArea = new TouchDelegate(delegateArea, delegate); | |
// Give the delegate to an ancestor of the view we're delegating the area to | |
if (View.class.isInstance(delegate.getParent())) { | |
((View) delegate.getParent()).setTouchDelegate(expandedArea); | |
} | |
}); | |
} | |
public static class Builder { | |
private View mViewToExtend; | |
private View mParentView; | |
private int mTop; // default is 0 | |
private int mBottom; // default is 0 | |
private int mLeft; // default is 0 | |
private int mRight; // default is 0 | |
private int mAll; // default is 0 | |
private Optional<View.OnClickListener> mViewClickListener = Optional.absent(); | |
private Builder(final View pViewToExtend) { | |
this.mViewToExtend = pViewToExtend; | |
} | |
/** | |
* Initialise with the view to want to extend the touch area of | |
* | |
* @param pViewToExtend | |
* @return | |
*/ | |
public static Builder with(final View pViewToExtend) { | |
Preconditions.checkNotNull(pViewToExtend, "Must pass in a view to extend the touch area of!"); | |
return new Builder(pViewToExtend); | |
} | |
public Builder parentView(final View mParentView) { | |
Preconditions.checkNotNull(mParentView, "Must pass in a parentview!"); | |
this.mParentView = mParentView; | |
return this; | |
} | |
public Builder top(final int pPx) { | |
this.mTop = pPx; | |
return this; | |
} | |
public Builder bottom(final int pPx) { | |
this.mBottom = pPx; | |
return this; | |
} | |
public Builder left(final int pPx) { | |
this.mLeft = pPx; | |
return this; | |
} | |
public Builder right(final int pPx) { | |
this.mRight = pPx; | |
return this; | |
} | |
public Builder all(final int pPx) { | |
this.mAll = pPx; | |
return this; | |
} | |
/** | |
* If the view you want extend has a click listener, you will need to now pass it in here. | |
* If you don't the click listener may not work. | |
* @param pViewClickListener | |
* @return | |
*/ | |
public Builder clickListener(final View.OnClickListener pViewClickListener) { | |
Preconditions.checkNotNull(mParentView, "Cannot pass in a null clicklistener!"); | |
this.mViewClickListener = Optional.fromNullable(pViewClickListener); | |
return this; | |
} | |
/** | |
* Must call this to create a TouchAreaExtender with set values. | |
* | |
* @return | |
*/ | |
public TouchAreaExtender build() { | |
return new TouchAreaExtender(this); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment