分享

两种Android判断view是否部分被遮挡(或者移出屏幕)的方法

 guitarhua 2017-08-15

部分内容参考http://blog.csdn.net/peidonghui/article/details/49583263,在此对原作者表示感谢。


在某些需求下,需要判断某一个View是否被遮挡,比如ListView的headerView中某一个View在ListView向上滑动到开始不可见时,在页面顶部固定显示一个View。在刚开始时,处理方式是在ListView的onScroll()中判断该View距离屏幕顶部的距离,来作为判断条件,网上好不容易找到解决方法,但测试的妹纸却在android 6.0的手机上测出兼容性BUG ,害得我周末跟妹纸约会都在想这个问题该怎么办,看来还是要仔细系统的研究一下自定义View和ViewGroup的相关问题


废话不多说,直接上代码。

1.当Android 的版本为6.0以下时


</pre><pre name="code" class="java">
</pre><pre name="code" class="java">
pullListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {


            }


            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                Rect rect = new Rect();
                line.getGlobalVisibleRect(rect);
                if ((rect.top < statusBarHeight + DimenUtil.dip2px(mContext, 97)) ) {
                    if (rl_choosed_tag.getVisibility() == View.INVISIBLE)
                        rl_choosed_tag.setVisibility(View.VISIBLE);
                } else {
                    if (rl_choosed_tag.getVisibility() == View.VISIBLE)
                        rl_choosed_tag.setVisibility(View.INVISIBLE);
                }
            }
        });


以上line为listView的headerView布局中的一个view,通过line.getGlobalVisibleRect(rect);来判断该view距离屏幕顶部的距离是否小于指定值(此处该临界值为

statusBarHeight + DimenUtil.dip2px(mContext, 97))来作为另外一个View是否显示的条件


2.当Android 的S版本为6.0时

在onScroll()中这样处理

if (Build.VERSION.SDK_INT >= 23) {
    if (isViewCovered(mSortFlowLayout)) {
        if (rl_choosed_tag.getVisibility() == View.VISIBLE)
            rl_choosed_tag.setVisibility(View.INVISIBLE);
    } else {
        if (rl_choosed_tag.getVisibility() == View.INVISIBLE)
            rl_choosed_tag.setVisibility(View.VISIBLE);
    }
}


涉及的isViewCovered()函数如下:

public boolean isViewCovered(final View view) {
    View currentView = view;

    Rect currentViewRect = new Rect();
    boolean partVisible = currentView.getGlobalVisibleRect(currentViewRect);
    boolean totalHeightVisible = (currentViewRect.bottom - currentViewRect.top) >= view.getMeasuredHeight();
    boolean totalWidthVisible = (currentViewRect.right - currentViewRect.left) >= view.getMeasuredWidth();
    boolean totalViewVisible = partVisible && totalHeightVisible && totalWidthVisible;
    if (!totalViewVisible)//if any part of the view is clipped by any of its parents,return true
        return true;

    while (currentView.getParent() instanceof ViewGroup) {
        ViewGroup currentParent = (ViewGroup) currentView.getParent();
        if (currentParent.getVisibility() != View.VISIBLE)//if the parent of view is not visible,return true
            return true;

        int start = indexOfViewInParent(currentView, currentParent);
        for (int i = start + 1; i < currentParent.getChildCount(); i++) {
            Rect viewRect = new Rect();
            view.getGlobalVisibleRect(viewRect);
            View otherView = currentParent.getChildAt(i);
            Rect otherViewRect = new Rect();
            otherView.getGlobalVisibleRect(otherViewRect);
            if (Rect.intersects(viewRect, otherViewRect))//if view intersects its older brother(covered),return true
                return true;
        }
        currentView = currentParent;
    }
    return false;
}


private int indexOfViewInParent(View view, ViewGroup parent) {
    int index;
    for (index = 0; index < parent.getChildCount(); index++) {
        if (parent.getChildAt(index) == view)
            break;
    }
    return index;
}

虽然一个简单的判断却还需要分版本不同单独处理,不过应该有更加简洁优雅的解决方案,欢迎各位给出指导。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多