第一种:
主要是以下的两个方法:
- View.getGlobalVisibleRect(rect); //以屏幕 左上角 为参考系的
- View.getLocalVisibleRect(rect); //以目标 View 左上角 为参考系
(View.getLocalVisibleRect(rect) 的 rect.left
恒等于 0 .)
判断是否可见:
boolean localVisibleRect = target.getLocalVisibleRect(rect);
进入方法的源码可以看到:
public final boolean getLocalVisibleRect(Rect r) {
final Point offset = mAttachInfo != null ? mAttachInfo.mPoint : new Point();
if (getGlobalVisibleRect(r, offset)) {
r.offset(-offset.x, -offset.y); // make r local
return true;
}
return false;
}
true : View 全部或者部分 可见
false : View 全部不可见
在返回 true (即 View 全部或者部分 可见)时,r.offset(-offset.x, -offset.y); // make r local
对 rect
的四个坐标进行了偏移.
如果是竖直的 Scrollview 里面的一个 View 在向上滑动的过程中,状态由 全部可见 --> 部分可见 --> 全部不可见
,其Rect.top
的变化是:
注: 这里获取 View 的高度是 height 像素.
- 全部可见 : Rect.top 恒为 0;
- 部分可见 : Rect.top 的值 由 0 --> height
- **全部不可见: ** 在全部不可见的瞬间,Rect.top 的值由 height 突变为 - height,其后随着滑动的距离越远,负值越大
**总结: ** 当 Rect.top 的值不为 0 时,View 要么部分可见,要么完全不可见.那么当我们需要 View 在有一点点不可见时就返回 false 可以这样处理:
//当 View 有一点点不可见时立即返回false!
public static boolean isVisibleLocal(View target){
Rect rect =new Rect();
target.getLocalVisibleRect(rect);
return rect.top==0;
}
可以使用的场景还是很多的,比如类似淘宝滑动可以悬停在顶部的 View,当View 滑到有一点不可见时就需要把 外层的 悬浮View 显示出来,当滑动的 View 完全可见时才把 悬浮的View 隐藏掉.
--------------------------------------------------------------------------------------------------------------------------
第二种:
view 可见性判断(代码尝试):
//java
class UIUtils {
public static int getScreenWidthInPx(Context context) {
DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
return dm.widthPixels;
}
public static int getScreenHeightInPx(Context context) {
DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
return dm.heightPixels;
}
}
//kotlin
fun isVisi(){
var sH = UIUtils.getScreenHeightInPx(activity)
var sW = UIUtils.getScreenWidthInPx(activity)
val location = IntArray(2)
view.getLocationInWindow(location);
var a = location[0] < sW
var b = location[1] < sH
if(a && b){
//在屏幕中是可见的
// todo something
return true
}
return false
}
------------------------------------------------------------------------------------------------------------------------------
第三种:
view 在屏幕中是否可见(代码实现版)
/**
* 判断当前view是否在屏幕可见
*/
public static boolean getLocalVisibleRect(Context context, View view, int offsetY) {
Point p = new Point();
((Activity) context).getWindowManager().getDefaultDisplay().getSize(p);
int screenWidth = p.x;
int screenHeight = p.y;
Rect rect = new Rect(0, 0, screenWidth, screenHeight);
int[] location = new int[2];
location[1] = location[1] + UIUtils.dip2px(context, offsetY);
view.getLocationInWindow(location);
view.setTag(location[1]);//存储y方向的位置
if (view.getLocalVisibleRect(rect)) {
return true;
} else {
return false;
}
}
//经常配合滑动事件使用
scrollView.setOnScrollListener(new ObservableScrollView.OnScrollListener() {
@Override
public void onScrollStateChanged(ObservableScrollView view, int scrollState) {
}
@Override
public void onScroll(ObservableScrollView view, boolean isTouchScroll, int l, int t, int oldl, int oldt) {
}
});
}
------------------------------------------------------------------------------------------------------------------------------
第四种
代码尝试:
public static boolean isVisible(final View view) {
if (view == null) {
return false;
}
if (!view.isShown()) {
return false;
}
final Rect actualPosition = new Rect();
view.getGlobalVisibleRect(actualPosition);
final Rect screen = new Rect(0, 0, getScreenWidth(), getScreenHeight());
return actualPosition.intersect(screen);
}