Add TouchExpander
This commit is contained in:
parent
a3c6d21a52
commit
5ce83d0314
@ -0,0 +1,85 @@
|
|||||||
|
package org.solovyev.android.calculator.view;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.Px;
|
||||||
|
import android.support.v4.view.ViewCompat;
|
||||||
|
import android.view.TouchDelegate;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
|
||||||
|
public class TouchExpander implements ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final View mView;
|
||||||
|
@NonNull
|
||||||
|
private final Rect mExtra;
|
||||||
|
// non-null when a TouchDelegate has been set
|
||||||
|
@Nullable
|
||||||
|
private View mParent;
|
||||||
|
|
||||||
|
private TouchExpander(@NonNull View view, @Px int extra) {
|
||||||
|
this(view, new Rect(extra, extra, extra, extra));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TouchExpander(@NonNull View view, @NonNull Rect extra) {
|
||||||
|
mView = view;
|
||||||
|
mExtra = extra;
|
||||||
|
|
||||||
|
attach();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void outset(@NonNull Rect rect, @NonNull Rect diff) {
|
||||||
|
rect.left -= diff.left;
|
||||||
|
rect.top -= diff.top;
|
||||||
|
rect.right += diff.right;
|
||||||
|
rect.bottom += diff.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static TouchExpander attach(@NonNull View view, @Px int extra) {
|
||||||
|
return new TouchExpander(view, extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static TouchExpander attach(@NonNull View view, @NonNull Rect extra) {
|
||||||
|
return new TouchExpander(view, extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attach() {
|
||||||
|
if (ViewCompat.isLaidOut(mView)) {
|
||||||
|
onLaidOut();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mView.getViewTreeObserver().addOnGlobalLayoutListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
if (!ViewCompat.isLaidOut(mView)) return;
|
||||||
|
mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||||
|
|
||||||
|
onLaidOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onLaidOut() {
|
||||||
|
if (!ViewCompat.isLaidOut(mView)) {
|
||||||
|
throw new IllegalStateException("View is not laid out");
|
||||||
|
}
|
||||||
|
final Rect hitRect = new Rect();
|
||||||
|
mView.getHitRect(hitRect);
|
||||||
|
outset(hitRect, mExtra);
|
||||||
|
|
||||||
|
mParent = (View) mView.getParent();
|
||||||
|
mParent.setTouchDelegate(new TouchDelegate(hitRect, mView));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void detach() {
|
||||||
|
mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||||
|
if (mParent != null) {
|
||||||
|
mParent.setTouchDelegate(null);
|
||||||
|
mParent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user