参考
Android View的可见性检查之 getLocalVisibleRect与 getGlobalVisibleRect
getGlobalVisibleRect() 与 getLocalVisibleRect()
-
getGlobalVisibleRect()
是view可见区域相对于屏幕来说
的坐标位置. -
getLocalVisibleRect()
是view可见区域相对于自己坐标
的位置. -
一定要记清楚是
可见区域
.
getGlobalVisibleRect(rect);
是以屏幕左上角为参考系,
判断view有一部分在屏幕中,返回true(没有被父View遮挡)。
反之,如果它全部被父View遮挡住或者本身就是不可见的,返回false。
getLocalVisibleRect(rect);
- 当View可见时,以自身View左上角为参考系,坐标系的原点为View自己的坐标原点。
- 当View不可见时,以父控件左上角为参考系,坐标系的原点为View的父控件的坐标原点。
DisplayUtil 工具类:
import android.content.Context;
import android.graphics.Point;
import android.view.Display;
import android.view.WindowManager;
public class DisplayUtil {
/**
* 获取屏幕的实际高度
*/
public static int getScreenRealWidth(Context context) {
try {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point outSize = new Point();
display.getRealSize(outSize);
return outSize.x;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return 0;
}
/**
* 获取屏幕的实际高度
*/
public static int getScreenRealHeight(Context context) {
try {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point outSize = new Point();
display.getRealSize(outSize);
return outSize.y;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return 0;
}
/**
* 获取状态栏的高度
*
* @param context
* @return
*/
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources()
.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
/**
* 获取导航栏的高度
*
* @param context
* @return
*/
public static int getNavBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources()
.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}
test2.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light">
<TextView
android:id="@+id/tv"
android:layout_width="300dp"
android:layout_height="150dp"
android:background="@android:color/holo_orange_light"
android:text=""
android:textColor="@android:color/black" />
<View
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@android:color/holo_red_dark" />
<View
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="@android:color/holo_green_dark" />
</RelativeLayout>
TestActivity.java :
import android.annotation.SuppressLint;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class TestActivity extends AppCompatActivity {
private static final String TAG = TestActivity.class.getSimpleName();
private TextView mTv;
private RelativeLayout mRoot;
private int lastX = 0;
private int lastY = 0;
@Override
@SuppressLint("ClickableViewAccessibility")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test2);
mRoot = findViewById(R.id.root);
mTv = findViewById(R.id.tv);
// 屏幕尺寸 : 1920*990,三个均包含状态栏高度,不包含导航栏高度
{
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
Log.e(TAG, "1 width = " + dm.widthPixels
+ ", height = " + dm.heightPixels);
//获取Android屏幕尺寸
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Log.e(TAG, "2 width = " + size.x
+ ", height = " + size.y);
DisplayMetrics metrics = getResources().getDisplayMetrics();
Log.e(TAG, "3 width = " + metrics.widthPixels
+ ", height = " + metrics.heightPixels);
}
// 屏幕尺寸 : 1920*1080,三个均包含状态栏高度 + 导航栏高度
{
mRoot.post(new Runnable() {
@Override
public void run() {
Log.e(TAG, "decorView "
+ "width = " + getWindow().getDecorView().getWidth()//1920
+ ",height = " + getWindow().getDecorView().getHeight()//1080
+ " ; root "
+ "width = " + mRoot.getWidth()//1920
+ ",height = " + mRoot.getHeight());//1080
}
});
int height = DisplayUtil.getScreenRealHeight(this);
Log.e(TAG, "height = " + height);//1080
int width = DisplayUtil.getScreenRealWidth(this);
Log.e(TAG, "width = " + width);//1920
}
// 状态栏=84 , 导航栏=90
{
int statusBarHeight = DisplayUtil.getStatusBarHeight(this);
Log.e(TAG, "statusBarHeight = " + statusBarHeight);
int navigationBarHeight = DisplayUtil.getNavBarHeight(this);
Log.e(TAG, "navigationBarHeight = " + navigationBarHeight);
}
mTv.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("SetTextI18n")
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
int dy = (int) event.getRawY() - lastY;
int left = v.getLeft() + dx;
int top = v.getTop() + dy;
int right = v.getRight() + dx;
int bottom = v.getBottom() + dy;
v.layout(left, top, right, bottom);
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
//getLocalVisibleRect的作用是获取视图本身可见的坐标区域,
// 坐标以自己的左上角为原点(0,0)
//只要该视图没有被遮挡,targetView.getLocalVisibleRect()的坐标总是等于:
//(0, 0, targetView.getwidth(), targetView.getHeight())
Rect localRect = new Rect();
v.getLocalVisibleRect(localRect);
//getGlobalVisibleRect方法的作用是获取视图在屏幕坐标中的可视区域
Rect globalRect = new Rect();
//globalOffset的值就是targetView原点偏离屏幕坐标原点的距离。
Point globalOffset = new Point();
v.getGlobalVisibleRect(globalRect, globalOffset);
Rect rect = new Rect();
mTv.getWindowVisibleDisplayFrame(rect);
mTv.setText("local = " + localRect.toString()
+ "\n" + "global = " + globalRect.toString()
+ "\n" + "globalOffset = " + globalOffset.x + "," + globalOffset.y
+ "\n" + "statusBar top = " + rect.top
+ "\n" + "navigationBar top = " + (rect.bottom)
);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
}
}