Skip to content

Instantly share code, notes, and snippets.

@dominicthomas
Last active November 1, 2016 07:28
Show Gist options
  • Save dominicthomas/258310a2ab1bc4e976d9 to your computer and use it in GitHub Desktop.
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.
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