【问题标题】:RecyclerView crashes on scrollingRecyclerView 在滚动时崩溃
【发布时间】:2016-11-08 21:13:19
【问题描述】:

我有一些以水平网格排列的图像。我想使用键事件从左到右和从右到左移动我的网格。当我穿过网格时发生了两件事

  1. 第二个位置的项目被选中。例如,我在位置 0 并想选择位置 1 的下一项,但我的网格选择位置 2 的项并跳过位置 1 的项。

  2. 滚动时出现空指针异常

    if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)
      {
         if (mCurrentSelectedPosition + 1 < getItemCount()) {
        Log.e("current position1",Integer.toString(mCurrentSelectedPosition));
    
        gridHolder = (GridView_Holder) mRecyclerView.findViewHolderForPosition(mCurrentSelectedPosition);
        gridHolder.itemView.setSelected(false);
        notifyItemChanged(mCurrentSelectedPosition);
        notifyDataSetChanged();
    
        int lastItem = lm.findLastCompletelyVisibleItemPosition();
        Log.e("last item",Integer.toString(lastItem));
    
        if ((mCurrentSelectedPosition + 1) > lastItem) {
            //  Log.e("Is less", "true");
            recyclerView.smoothScrollToPosition(mCurrentSelectedPosition + 1);
            Log.e("current position2",Integer.toString(mCurrentSelectedPosition));
    
        } else {
            gridHolder = (GridView_Holder) mRecyclerView.findViewHolderForPosition(mCurrentSelectedPosition + 1);
            gridHolder.itemView.setSelected(true);
            Log.e("current position3",Integer.toString(mCurrentSelectedPosition));
        }
    
        mCurrentSelectedPosition += 1;
        Log.e("current position4",Integer.toString(mCurrentSelectedPosition));
    }
    return true;
    }
    

滚动监听器

gridRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
        @Override
        public void onScrolled(RecyclerView recyclerView, int x, int y)
        {
            super.onScrolled(recyclerView, x, y);
            try {
                GridView_Holder gridHolder;
                gridHolder= (GridView_Holder) recyclerView.findViewHolderForPosition(adapter.mCurrentSelectedPosition);

                gridHolder.itemView.setSelected(true);
            }catch(Exception e){
               Log.e("exception",e.getMessage());
           }

        }

这是我的日志

java.lang.NullPointerException: Attempt to read from field 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' on a null object reference
at com.winettv.recylcerviewwithdpad.GridView_Recycler_Adapter$1.onKey(GridView_Recycler_Adapter.java:193)
at android.view.View.dispatchKeyEvent(View.java:9230)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1635)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.widget.ScrollView.dispatchKeyEvent(ScrollView.java:379)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1640)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2395)
at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1727)
at android.app.Activity.dispatchKeyEvent(Activity.java:2725)
at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:543)
at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:53)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:315)

【问题讨论】:

标签: java android android-recyclerview scroller key-events


【解决方案1】:

在代码中gridHolder.itemView.setSelected(true); gridHolder 为空。

这样改代码试试。

if ((mCurrentSelectedPosition + 1) > lastItem) {
        //  Log.e("Is less", "true");
        recyclerView.smoothScrollToPosition(mCurrentSelectedPosition);
        Log.e("current position2",Integer.toString(mCurrentSelectedPosition));

    } else {
        gridHolder = (GridView_Holder) mRecyclerView.findViewHolderForPosition(mCurrentSelectedPosition);
        gridHolder.itemView.setSelected(true);
        Log.e("current position3",Integer.toString(mCurrentSelectedPosition));
    }

崩溃的原因。

【讨论】:

  • 这并不能解决我的问题我仍然面临同样的崩溃
【解决方案2】:

当我在滚动期间开发带有自定义翻译的库时,我遇到了同样的问题。仅在快速滚动中,当我尝试从 List 访问 View 元素时,它为空,这里是 NPE。

所以有一个非常简单的解决方案,只是跳过元素,它是空的,然后继续新的。在我的情况下是这样的:

// Other init....
for (int i = 0; i < MainListView.getChildCount; i++) {
   if (MainListView.getChildAt(i) == null)
      continue;
   // Continue base behavior
}

当我们尝试访问正在重绘的 View 时,基于 ScrollView(它是 RecycleView、ListView 等的父级)会发生这种情况。无论如何,只需简单的 Null 检查即可解决您的问题。

更新 1:

同样基于 RecyclerView 的缓存视图布局,你需要另一种选择。见下文。

gridRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
        @Override
        public void onScrolled(RecyclerView recyclerView, int x, int y)
        {
            super.onScrolled(recyclerView, x, y);
            GridView_Holder gridHolder;
            gridHolder= (GridView_Holder) recyclerView.findViewHolderForPosition(adapter.mCurrentSelectedPosition);
            if (gridHolder != null && gridHolder.itemView != null) {
                   gridHolder.itemView.setSelected(true);
            }
        }
}

【讨论】:

  • 我在滚动时崩溃了。我已经添加了 onScrollListener 的代码。请检查。
【解决方案3】:

根据错误很明显

(GridView_Holder)mRecyclerView.findViewHolderForPosition(mCurrentSelectedPosition);

为空。这就是崩溃的原因。

您可以参考以下链接

FindViewHolderForPosition return null when card's not in vision

RecyclerView - findViewHolderForPosition always returns null when onBindViewHolder is not called

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-12
    • 2021-12-31
    • 2017-12-17
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多