Skip to content

Instantly share code, notes, and snippets.

@mrenouf
Created March 16, 2018 15:22
Show Gist options
  • Save mrenouf/e4c7c780af6d4d21a5e3d7d427292f7b to your computer and use it in GitHub Desktop.
Save mrenouf/e4c7c780af6d4d21a5e3d7d427292f7b to your computer and use it in GitHub Desktop.
package com.example.mrenouf.touchtest;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import java.util.ArrayList;
import java.util.List;
public final class ViewGroups {
private ViewGroups() {}
private static final List<View> tmpViewList = new ArrayList<>();
private static final Rect tmpRect = new Rect();
private static ViewGroup getParentViewGroup(View view) {
ViewParent parent = view.getParent();
if (parent instanceof ViewGroup) {
return (ViewGroup) parent;
}
return null;
}
public static boolean isVisiblePointWithinView(View view, float x, float y) {
if (view.getVisibility() != View.VISIBLE) {
return false;
}
// Test view is not entirely clipped by parents
if (view.getGlobalVisibleRect(tmpRect)) {
// transform touch point from local (view) to global (screen) coordinates
x += tmpRect.left;
y += tmpRect.top;
// Verify provided point is actually within the view
if (!tmpRect.contains((int) x, (int) y)) {
return false;
}
View child = view;
ViewGroup parent = ((ViewGroup) child.getParent());
while (parent != null) {
// Check this view is not covered by a sibling
getTopSortedChildren(parent, tmpViewList);
for (int i = 0; i < tmpViewList.size(); i++) {
View sibling = tmpViewList.get(i);
if (sibling == child) {
// view is visible, not covered
break;
} else {
if (sibling.getVisibility() != View.VISIBLE) {
continue;
}
// Another view is on top, check if occluding.
sibling.getGlobalVisibleRect(tmpRect);
if (tmpRect.contains((int) x, (int) y)) {
// The point given is covered by this view
return false;
}
}
}
child = parent;
parent = getParentViewGroup(child);
}
}
return true;
}
private static void getTopSortedChildren(ViewGroup parent, List<View> out) {
out.clear();
final int childCount = parent.getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
out.add(parent.getChildAt(i));
}
out.sort(ViewGroups::compare);
}
private static int compare(View lhs, View rhs) {
final float lz = ViewCompat.getZ(lhs);
final float rz = ViewCompat.getZ(rhs);
if (lz > rz) {
return -1;
} else if (lz < rz) {
return 1;
}
return 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment