下面列出了android.view.View#getGlobalVisibleRect ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* @param v
* @return 得到view当前真实显示的位置和大小,超过屏幕显示的大小就是0
*/
public static Rect getRealVisibleRect(View v) {
//得到view的左上角坐标(相对于整个屏幕)
int[] position = new int[2];
v.getLocationOnScreen(position);
Rect bounds = new Rect();
boolean isInScreen = v.getGlobalVisibleRect(bounds);
Rect mRect = new Rect();
mRect.left = position[0];
mRect.top = position[1];
if (isInScreen) {
mRect.right = mRect.left + bounds.width();
mRect.bottom = mRect.top + bounds.height();
}else {
mRect.right = mRect.left;
mRect.bottom = mRect.top;
}
return mRect;
}
/**
* get the tag of the first visible child in this layout
*
* @return tag of the first visible child or null
*/
public String getFirstVisibleCardTag() {
final int count = getChildCount();
if (count == 0)
return null;
for (int index = 0; index < count; ++index) {
//check the position of each view.
View child = getChildAt(index);
if (child.getGlobalVisibleRect(mChildRect) == true)
return (String) child.getTag();
}
return null;
}
/**
* get the tag of the first visible child in this layout
*
* @return tag of the first visible child or null
*/
public String getFirstVisibleCardTag() {
final int count = getChildCount();
if (count == 0)
return null;
for (int index = 0; index < count; ++index) {
//check the position of each view.
View child = getChildAt(index);
if (child.getGlobalVisibleRect(mChildRect) == true)
return (String) child.getTag();
}
return null;
}
/**
* @param v
* @return 得到view当前真实显示的位置和大小,超过屏幕显示的大小就是0
*/
public static Rect getRealVisibleRect(View v) {
//得到view的左上角坐标(相对于整个屏幕)
int[] position = new int[2];
v.getLocationOnScreen(position);
Rect bounds = new Rect();
boolean isInScreen = v.getGlobalVisibleRect(bounds);
Rect mRect = new Rect();
mRect.left = position[0];
mRect.top = position[1];
if (isInScreen) {
mRect.right = mRect.left + bounds.width();
mRect.bottom = mRect.top + bounds.height();
}else {
mRect.right = mRect.left;
mRect.bottom = mRect.top;
}
return mRect;
}
private View findViewAtPosition(View parent, int x, int y) {
if(parent instanceof ViewPager){
Rect rect = new Rect();
parent.getGlobalVisibleRect(rect);
if (rect.contains(x, y)) {
return parent;
}
}else if(parent instanceof ViewGroup){
ViewGroup viewGroup = (ViewGroup)parent;
final int length = viewGroup.getChildCount();
for (int i = 0; i < length; i++) {
View child = viewGroup.getChildAt(i);
View viewAtPosition = findViewAtPosition(child, x, y);
if (viewAtPosition != null) {
return viewAtPosition;
}
}
return null;
}
return null;
}
private static boolean isViewVisible(View view) {
if (view.getVisibility() != View.VISIBLE) {
return false;
}
ViewParent parent = view.getParent();
if (parent != null && parent instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) parent;
int width = viewGroup.getWidth();
Rect rect = new Rect();
boolean globalVisibleRect = view.getGlobalVisibleRect(rect);
int visibleWidth = rect.width();
return globalVisibleRect && visibleWidth >= width / 2;
}
return view.getGlobalVisibleRect(new Rect());
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if ( v instanceof EditText) {
Rect outRect = new Rect();
v.getGlobalVisibleRect(outRect);
if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
v.clearFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
return super.dispatchTouchEvent( event );
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (v instanceof EditText) {
Rect outRect = new Rect();
v.getGlobalVisibleRect(outRect);
if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
v.clearFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
return super.dispatchTouchEvent(event);
}
/**
* Determines if the supplied {@link View} is visible to the user, which requires that it be
* marked visible, that all its parents are visible, that it and all parents have alpha greater
* than 0, and that it has non-zero size. This code attempts to replicate the protected method
* {@code View.isVisibleToUser}.
*
* @param view The {@link View} to evaluate
* @return {@code true} if {@code view} is visible to the user
*/
@RequiresApi(Build.VERSION_CODES.HONEYCOMB) // Uses View#getAlpha
public static boolean isVisibleToUser(View view) {
if (view == null) {
return false;
}
Object current = view;
while (current instanceof View) {
View currentView = (View) current;
if ((currentView.getAlpha() <= 0) || (currentView.getVisibility() != View.VISIBLE)) {
return false;
}
current = currentView.getParent();
}
return view.getGlobalVisibleRect(new Rect());
}
public static Rect computerBound(View view) {
Rect bounds = new Rect();
if (view != null) {
view.getGlobalVisibleRect(bounds);
}
return bounds;
}
/**
* 反射给View注册监听
*/
private void hookViewClick(View view) throws Exception {
int visibility = view.getVisibility();
if (visibility == 4 || visibility == 8) {
return;
}
if (!view.getGlobalVisibleRect(new Rect())) {
return;
}
Class viewClass = Class.forName("android.view.View");
Method getListenerInfoMethod = viewClass.getDeclaredMethod("getListenerInfo");
if (!getListenerInfoMethod.isAccessible()) {
getListenerInfoMethod.setAccessible(true);
}
Object listenerInfoObject = getListenerInfoMethod.invoke(view);
Class mListenerInfoClass = Class.forName("android.view.View$ListenerInfo");
Field mOnClickListenerField = mListenerInfoClass.getDeclaredField("mOnTouchListener");
// Log.d("sanbo", view.hashCode() + "-----" + HeatMap.HookTouchListener.class.getName() +
// " <-------> " + mOnClickListenerField.getType().getName());
mOnClickListenerField.setAccessible(true);
Object touchListenerObj = mOnClickListenerField.get(listenerInfoObject);
if (!(touchListenerObj instanceof HookTouchListener)) {
// printLog(view, touchListenerObj);
HookTouchListener touchListenerProxy =
new HookTouchListener((View.OnTouchListener) touchListenerObj);
mOnClickListenerField.set(listenerInfoObject, touchListenerProxy);
}
}
/**
* 适配Android7.0
*
* @param anchor
*/
@Override
public void showAsDropDown(View anchor) {
setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
refreshData();
if (Build.VERSION.SDK_INT >= 25) {
Rect rect = new Rect();
anchor.getGlobalVisibleRect(rect);
int mHeight = Utils.getScreenHeight(mContext) - rect.bottom;
setHeight(mHeight);
super.showAsDropDown(anchor);
} else if (Build.VERSION.SDK_INT == 24) {
int[] a = new int[2];
anchor.getLocationInWindow(a);
int heignt = anchor.getHeight();
this.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.NO_GRAVITY, 0, a[1] + heignt);
this.update();
} else {
super.showAsDropDown(anchor);
}
int height = 0;
if (mRootView.getMeasuredHeight() == 0) {
height = getHeight();
} else {
height = mRootView.getMeasuredHeight();
}
createInAnimation(mContext, -height);
}
public void showAsDropDown(PopupWindow window, View anchor) {
if (Build.VERSION.SDK_INT >= 24) {
Rect visibleFrame = new Rect();
anchor.getGlobalVisibleRect(visibleFrame);
int height = anchor.getResources().getDisplayMetrics().heightPixels - visibleFrame.bottom;
window.setHeight(height);
}
popupWindow.showAsDropDown(anchor);
}
protected void stripOffscreenViews() {
if (mTransitioningViews == null) {
return;
}
Rect r = new Rect();
for (int i = mTransitioningViews.size() - 1; i >= 0; i--) {
View view = mTransitioningViews.get(i);
if (!view.getGlobalVisibleRect(r)) {
mTransitioningViews.remove(i);
mStrippedTransitioningViews.add(view);
}
}
}
@Override
public void getOutline(View view, Outline outline) {
Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
int leftMargin = 0;
int topMargin = 0;
Rect selfRect = new Rect(leftMargin, topMargin,
rect.right - rect.left - leftMargin, rect.bottom - rect.top - topMargin);
if(mRect!=null){
selfRect = mRect;
}
outline.setRoundRect(selfRect, mRadius);
}
public void showPopupAsDropDown(View anchor){
if(isShowMaskView){
addMask(anchor.getWindowToken());
}
Rect rect = new Rect();
anchor.getGlobalVisibleRect(rect);
int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom;
setHeight(h);
this.showAsDropDown(anchor);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (v instanceof EditText) {
Rect outRect = new Rect();
v.getGlobalVisibleRect(outRect);
if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
v.clearFocus();
hideKeyboard();
}
}
}
return super.dispatchTouchEvent(event);
}
public static boolean isViewVisible(View view) {
return view.getGlobalVisibleRect(new Rect());
}
/**
* @param targetView View for which we want to get on-screen location
* @return true if view position is changed, false otherwise
*/
private boolean init(@NonNull View targetView) {
// If view is not attached then we can't get it's position
if (targetView.getWindowToken() == null) {
return false;
}
tmpViewRect.set(view);
targetView.getLocationOnScreen(tmpLocation);
view.set(0, 0, targetView.getWidth(), targetView.getHeight());
view.offset(tmpLocation[0], tmpLocation[1]);
viewport.set(targetView.getPaddingLeft(),
targetView.getPaddingTop(),
targetView.getWidth() - targetView.getPaddingRight(),
targetView.getHeight() - targetView.getPaddingBottom());
viewport.offset(tmpLocation[0], tmpLocation[1]);
boolean isVisible = targetView.getGlobalVisibleRect(visible);
if (!isVisible) {
// Assuming we are starting from center of invisible view
visible.set(view.centerX(), view.centerY(), view.centerX() + 1, view.centerY() + 1);
}
if (targetView instanceof ImageView) {
ImageView imageView = (ImageView) targetView;
Drawable drawable = imageView.getDrawable();
if (drawable == null) {
image.set(viewport);
} else {
final int drawableWidth = drawable.getIntrinsicWidth();
final int drawableHeight = drawable.getIntrinsicHeight();
// Getting image position within the view
ImageViewHelper.applyScaleType(imageView.getScaleType(),
drawableWidth, drawableHeight, viewport.width(), viewport.height(),
imageView.getImageMatrix(), tmpMatrix);
tmpSrc.set(0f, 0f, drawableWidth, drawableHeight);
tmpMatrix.mapRect(tmpDst, tmpSrc);
// Calculating image position on screen
image.left = viewport.left + (int) tmpDst.left;
image.top = viewport.top + (int) tmpDst.top;
image.right = viewport.left + (int) tmpDst.right;
image.bottom = viewport.top + (int) tmpDst.bottom;
}
} else {
image.set(viewport);
}
return !tmpViewRect.equals(view);
}
/**
* 判断view是否显示在屏幕上。 但不能判断被上层视图遮盖的情况。
* 参考:https://juejin.im/entry/5dae45f8f265da5ba46f6106 、 https://www.jianshu.com/p/30b0ae304518
*
* @return true -> yes, false -> no
*/
public static boolean isVisibleToUser(View view) {
if (view == null || view.getVisibility() != View.VISIBLE) {
return false;
}
Rect tempVisibleRect = new Rect();
return ViewCompat.isAttachedToWindow(view) && view.getGlobalVisibleRect(tempVisibleRect);
}