findFirstVisibleItemPositions不适合recycleview机器人工作

问题描述:

我有这样的代码:findFirstVisibleItemPositions不适合recycleview机器人工作

mRecycleView.setOnScrollListener(new RecyclerView.OnScrollListener() { 
    @Override 
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
     super.onScrolled(recyclerView, dx, dy); 
     int[] firstVisibleItemPositions = new int[getResources().getInteger(R.integer.news_numbers_column)]; 
     int pastVisiblesItems = ((StaggeredGridLayoutManager)getLayoutManager()).findFirstVisibleItemPositions(firstVisibleItemPositions)[0]; 
    } 
}); 

当我滚动我recycleview我得到这个错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.support.v7.widget.OrientationHelper.getStartAfterPadding()' on a null object reference 
at android.support.v7.widget.StaggeredGridLayoutManager$Span.findOneVisibleChild(StaggeredGridLayoutManager.java:2177) 
at android.support.v7.widget.StaggeredGridLayoutManager$Span.findFirstVisibleItemPosition(StaggeredGridLayoutManager.java:2153) 
at android.support.v7.widget.StaggeredGridLayoutManager.findFirstVisibleItemPositions(StaggeredGridLayoutManager.java:806) 
at info.lanouvelletribune.apps.android.ui.fragments.NewsFragment$1.onScrollStateChanged(NewsFragment.java:90) 
at android.support.v7.widget.RecyclerView.setScrollState(RecyclerView.java:751) 
at android.support.v7.widget.RecyclerView.onInterceptTouchEvent(RecyclerView.java:1535) 
at com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView.onInterceptTouchEvent(ObservableRecyclerView.java:188) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2060) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2431) 
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2173) 
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2390) 
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1741) 
at android.app.Activity.dispatchTouchEvent(Activity.java:2826) 
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2351) 
at android.view.View.dispatchPointerEvent(View.java:8590) 
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4098) 
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3964) 
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3488) 
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3541) 
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3507) 
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3515) 
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3488) 
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3541) 
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3507) 
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3617) 
at android 

我该怎么做才能处理此错误,并得到第一个可见的项目位置?

+0

我想它在第一次初始化时发生。 现在,请在调用findFirstVisible之前检查它是否有任何孩子,如果您可以在b.android.com上创建一个错误报告,那也是很好的。 – yigit 2015-04-07 04:42:56

我这个代码,测试它,我用循环视图参数正常工作与我

int positionView = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition(); 

+0

很好的答案 – 2015-08-31 16:01:32

+0

你救了我,爽! – 2017-08-03 12:55:17

试试这个:

int position = layoutManager.findFirstVisibleItemPositions(null)[0]; 

其中layoutManager是你在你的recyclerview设置。

例如,

layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL); 
mrecyclerView.setLayoutManager(layoutManager); 
+0

此解决方案适用于我。请告诉我解决方案中是否有问题。 layoutManager.findFirstVisibleItemPositions(null)将返回一个新的数组。 [link](https://developer.android.com/reference/android/support/v7/widget/StaggeredGridLayoutManager.html#findFirstVisibleItemPositions(int [])) – 2015-04-09 11:01:23

这是RecyclerView StaggeredGridLayoutManager了一个错误:

https://code.google.com/p/android/issues/detail?id=180521

https://code.google.com/p/android/issues/detail?id=181461

一种解决方法是尝试/捕获异常:

try { 
    ((StaggeredGridLayoutManager)getLayoutManager()).findFirstVisibleItemPositions(firstVisibleItemPositions); 
} catch (NullPointerException ex) { 
    // workaround for RecyclerView bug. assume not laid out, so no items visible 
    firstVisibleItemPositions[0] = RecyclerView.NO_POSITION; 
    firstVisibleItemPositions[1] = RecyclerView.NO_POSITION; 
} 

您可以使用此:

int[] firstVisibleItemPositions = new int[yourNumberOfColumns]; 
int pastVisiblesItems = layoutManager.findFirstVisibleItemPositions(firstVisibleItem‌​Positions)[0]; 

如果您正在使用StaggeredGridLayoutManager你可以找到findLastVisibleItemPositions象下面这样:

int visibleThreshold =1; 
final StaggeredGridLayoutManager linearLayoutManager = (StaggeredGridLayoutManager) mRecyclerViewAllPost.getLayoutManager(); 
    mRecyclerViewAllPost.addOnScrollListener(new RecyclerView.OnScrollListener() { 
     @Override 
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      super.onScrolled(recyclerView, dx, dy); 

      int[] lastVisibleItemPositions = linearLayoutManager.findLastVisibleItemPositions(null); 
      int lastVisibleItem = getLastVisibleItem(lastVisibleItemPositions); 
      int totalItemCount = linearLayoutManager.getItemCount(); 
      if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) { 
       print("load more item "); 
       isLoading = true; 
      } 
     } 
    }); 

getLastVisibleItem方法如下:

public int getLastVisibleItem(int[] lastVisibleItemPositions) { 
    int maxSize = 0; 
    for (int i = 0; i < lastVisibleItemPositions.length; i++) { 
     if (i == 0) { 
      maxSize = lastVisibleItemPositions[i]; 
     } 
     else if (lastVisibleItemPositions[i] > maxSize) { 
      maxSize = lastVisibleItemPositions[i]; 
     } 
    } 
    return maxSize; 
}