1. 监听思路
NestedScrollView
内嵌 RecyclerView
时,RecyclerView
的滑动监听很大可能监听不到,所以我们只能通过对NestedScrollView
的监听进行RecyclerView
的滑动判断;
2. 基本布局
别问我为什么有这种布局,你也会遇到的;(通用布局)
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/baseSwipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v4.widget.NestedScrollView
android:id="@+id/baseViewContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/baseViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
这里注意 需要给 NestedScrollView
添加下面属性:
android:fillViewport="true"
3. RecyclerView
初始化
//设置layoutManager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
// auto measure : true
linearLayoutManager.setSmoothScrollbarEnabled(true);
linearLayoutManager.setAutoMeasureEnabled(true);
linearLayoutManager.setOrientation(VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
// 设置为 true
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new DefaultItemAnimator());
// 设置为 false
recyclerView.setNestedScrollingEnabled(false);
4. NestedScrollView
滑动监听
mNestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY > oldScrollY) {
// 向下滑动
}
if (scrollY < oldScrollY) {
// 向上滑动
}
if (scrollY == 0) {
// 顶部
}
if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
// 底部
}
}
});
5. 结语
好吧,通过对 NestedScrollView
的监听,对RecyclerView
的数据操作即可!
6. 题外话(一) RecyclerView
的滑动监听
简单实现
RecyclerView
的监听
重写滑动监听事件
/**
* 重写RecyclerView.OnScrollListener 判断滑动向上,向下,顶部,底部
*/
public static abstract class OnVerticalScrollListener extends RecyclerView.OnScrollListener {
@Override
public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LogUtil.e("ddd" + dy);
if (!recyclerView.canScrollVertically(-1)) {
onScrolledToTop();
} else if (!recyclerView.canScrollVertically(1)) {
onScrolledToBottom();
} else if (dy < 0) {
onScrolledUp();
} else if (dy > 0) {
onScrolledDown();
}
}
//向上滑动
public void onScrolledUp() {
}
//向下滑动
public void onScrolledDown() {
}
//滑动底部
public void onScrolledToTop() {
}
//滑动顶部
public void onScrolledToBottom() {
}
}
使用
protected RecyclerView.OnScrollListener getOnScrollListener() {
//上下滑动监听
return new OnVerticalScrollListener() {
@Override
public void onScrolledToBottom() {
if (!isLoading) {
page++;
onLoadNextPage(page);
isLoading = true;
}
}
};
}
7. 题外话(二)RecyclerAdapter
的数据改变监听
给 adapter 注册一个观察者,执行下面notifyxxx
方法的时候,会调用方法;
notifyDataSetChanged()
notifyItemChanged()
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
checkAdapterEmpty();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
checkAdapterEmpty();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
super.onItemRangeRemoved(positionStart, itemCount);
checkAdapterEmpty();
}
});