CoordinatorLayout+AppbarLayout与下

2019-11-07  本文已影响0人  百事可乐99

项目中以前的旧代码是使用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{
                    //关闭下拉刷新功能
                }
            }
        });
    }
上一篇下一篇

猜你喜欢

热点阅读