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