项目开发中最近 经常遇到这样的需求,就是ListView或者RecyclerView中的ItemView 被展示或者不可见的时候 要被能监听到
这个通常是打点的需求。
这里我们能想到的是 滚动的监听,无论是ListView或者RecyclerView的监听事件
要监听的就是第一个显示的position以及最后显示的position,然后对比上次显示的第一个position和最后一个position。
对比之后我们就可以知道 哪些范围的position退出了,哪些范围的position新进来的。
1、ListView的监听
private AbsListView.OnScrollListener listiewScrollListener=new AbsListView.OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int paramVisibleItemCount, int totalItemCount) {
int firstVisible = view.getFirstVisiblePosition();
int lastVisible = view.getLastVisiblePosition();
dealScrollEvent(firstVisible, lastVisible);
}
};
2、RecyclerView滚动的监听
private RecyclerView.OnScrollListener recyclerScrollListener=new RecyclerView.OnScrollListener(){
//RecyclerVew
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager layoutManager= (LinearLayoutManager) recyclerView.getLayoutManager();
if (layoutManager!=null){
int firstVisible = layoutManager.findFirstVisibleItemPosition();
int lastVisible = layoutManager.findLastVisibleItemPosition();
int visibleItemCount = lastVisible - firstVisible;
if (lastVisible == 0) {
visibleItemCount = 0;
}
if (visibleItemCount != 0) {
dealScrollEvent(firstVisible, lastVisible);
}
}
}
};
RecyclerView的fistPosition是通过LayoutManager获取到的,我们还需要注意的是
//此方法常用作判断是否能下拉刷新,来解决滑动冲突
//int findFirstCompletelyVisibleItemPosition = layoutManager.findFirstCompletelyVisibleItemPosition();
//最后一个完整的可见的item位置
//int findLastCompletelyVisibleItemPosition = layoutManager.findLastCompletelyVisibleItemPosition();
获取完整的显示的view,这个跟或者position还是有差别的
int firstVisible = layoutManager.findFirstVisibleItemPosition();
int lastVisible = layoutManager.findLastVisibleItemPosition();
我们要精确的获取view的位置状态。
3 、我们获取到监听之后 就要分析
private void dealScrollEvent(int firstVisible, int lastVisible) {
int visibleItemCount = lastVisible - firstVisible;
if (visibleItemCount > 0) {
if (lastStart == -1) {
lastStart = firstVisible;
lastEnd = lastVisible;
for (int i = lastStart; i < lastEnd + 1; i++) {
if (listener!=null){
listener.onSelectEnterPosition(i);
}
}
} else {
if (firstVisible != lastStart) {
if (firstVisible > lastStart) {//向上滑动
for (int i = lastStart; i < firstVisible; i++) {
if (listener!=null){
listener.onSelectExitPosition(i);
}
}
} else {//向下滑动
for (int i = firstVisible; i < lastStart; i++) {
if (listener!=null){
listener.onSelectEnterPosition(i);
}
}
}
lastStart = firstVisible;
}
//
if (lastVisible != lastEnd) {
if (lastVisible > lastEnd) {//向上滑动
for (int i = lastEnd; i < lastVisible; i++) {
if (listener!=null){
listener.onSelectEnterPosition(i + 1);
}
}
} else {//向下滑动
for (int i = lastVisible; i < lastEnd; i++) {
if (listener!=null){
listener.onSelectExitPosition(i + 1);
}
}
}
lastEnd = lastVisible;
}
}
}
}
我们设置了两个回调,一个是进入的回调,一个是退出的回调
listener.onSelectEnterPosition(i);
listener.onSelectExitPosition(i);
OnItemEnterOrExitVisibleHelper helper = new OnItemEnterOrExitVisibleHelper();
helper.setListiewScrollListener(listview);
helper.setOnScrollStatusListener(listener);
private OnItemEnterOrExitVisibleHelper.OnScrollStatusListener listener = new OnItemEnterOrExitVisibleHelper.OnScrollStatusListener() {
public void onSelectEnterPosition(int postion) {
Log.v("xhw", "进入Enter:" + postion);
}
public void onSelectExitPosition(int postion) {
Log.v("xhw", "退出Exit:" + postion);
}
};
github:https://github.com/xuhuawei131/RecyclerViewItemVisible