美文网首页
CoordinatorLayout+AppbarLayout与下

CoordinatorLayout+AppbarLayout与下

作者: 百事可乐99 | 来源:发表于2019-11-07 11:07 被阅读0次

    项目中以前的旧代码是使用ListView实现列表,然后头部导航栏与TabLayout是使用自定义View实现CoordinatorLayout+AppbarLayout的效果的, 后来项目决定使用谷歌的新控件来替换以前的自定义View,中间下拉刷新就遇到了冲突。

    解决这个问题的时候,一开始方向不太对,想着去监听ListView下拉刷新的距离,当距离为0的时候让onIntercept返回false,不拦截事件,结果不知道为什么一直获取不到ListView下拉刷新的距离,猜测原因:
    为了让ListView配合CoordinatorLayout使用,使用了网上的重写ListView的方式:

    public class NoScrollListView extends ListView {
        public NoScrollListView(Context context) {
            super(context);
        }
    
        public NoScrollListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public NoScrollListView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
        }
    }
    

    这个处理会让ListView失去View复用的机制,然后我获取ListView滚动高度的方法是:

    listview.setOnScrollListener(new OnScrollListener() {
        private SparseArray recordSp = new SparseArray(0);
        private int mCurrentfirstVisibleItem = 0;
        
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
        
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                    int totalItemCount) {
            mCurrentfirstVisibleItem = arg1;
            View firstView = arg0.getChildAt(0);
            if (null != firstView) {
                ItemRecod itemRecord = (ItemRecod) recordSp.get(arg1);
                if (null == itemRecord) {
                    itemRecord = new ItemRecod();
                }
                itemRecord.height = firstView.getHeight();
                itemRecord.top = firstView.getTop();
                recordSp.append(arg1, itemRecord);
                int h = getScrollY();//滚动距离
                }
            }
        }
        
        private int getScrollY() {
            int height = 0;
            for (int i = 0; i < mCurrentfirstVisibleItem; i++) {
                ItemRecod itemRecod = (ItemRecod) recordSp.get(i);
                height += itemRecod.height;
            }
            ItemRecod itemRecod = (ItemRecod) recordSp.get(mCurrentfirstVisibleItem);
            if (null == itemRecod) {
                itemRecod = new ItemRecod();
            }
            return height - itemRecod.top;
        }
     
     
        class ItemRecod {
            int height = 0;
            int top = 0;
        }
    });
    

    由于上面重写ListView的问题,会导致第一个可见的item:firstVisibleItem一直为1,可见总量也是保持不变的,所以这种方法获取ListView滚动高度会一直为0.

    后来突然想到,我现在的滚动是依靠外面CoordinatorLayout+AppbarLayout来实现的,既然这样,那肯定直接通过监听AppbarLayout的滚动距离就可以了呀,找准了方向,解决问题就快了。直接谷歌监听AppbarLayout滚动的方法:

    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
                @Override
                public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                    if (verticalOffset == 0){
                        //没有滚动,打开下拉刷新功能
                    }else{
                        //关闭下拉刷新功能
                    }
                }
            });
        }
    

    相关文章

      网友评论

          本文标题:CoordinatorLayout+AppbarLayout与下

          本文链接:https://www.haomeiwen.com/subject/kqbmbctx.html