如何 判断一个 View 是否可见

第一种:

主要是以下的两个方法:

  • 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 像素.

  1. 全部可见 : Rect.top 恒为 0;
  2. 部分可见 : Rect.top 的值 由 0 --> height
  3. **全部不可见: ** 在全部不可见的瞬间,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);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值