部分内容参考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)
- return true;
-
- while (currentView.getParent() instanceof ViewGroup) {
- ViewGroup currentParent = (ViewGroup) currentView.getParent();
- if (currentParent.getVisibility() != View.VISIBLE)
- 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))
- 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;
- }
虽然一个简单的判断却还需要分版本不同单独处理,不过应该有更加简洁优雅的解决方案,欢迎各位给出指导。