Created
March 16, 2018 15:22
-
-
Save mrenouf/e4c7c780af6d4d21a5e3d7d427292f7b 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
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