Android 当列表被滚动时,getChild(索引)显示null(索引被弄乱)

Android 当列表被滚动时,getChild(索引)显示null(索引被弄乱),android,android-recyclerview,android-viewholder,Android,Android Recyclerview,Android Viewholder,我一直在为我的android应用程序使用SwipeableRecyclerView,以便为我的recyclerView启用滑动。RecyclerView包含一个CardView列表 我试图为向左滑动时将被删除的卡实现撤消功能(第一次滑动显示撤消,下一次滑动触发删除) 我正在尝试以下代码(我想部分工作) 当项目较多时(需要滚动) 返回导致应用程序崩溃的空引用 我怀疑我用了错误的方法来看待问题。我应该使用一些与viewholder相关的东西,我实际上有点困惑如何从viewholder获得您想要的视图

我一直在为我的android应用程序使用SwipeableRecyclerView,以便为我的recyclerView启用滑动。RecyclerView包含一个CardView列表

我试图为向左滑动时将被删除的卡实现撤消功能(第一次滑动显示撤消,下一次滑动触发删除)

我正在尝试以下代码(我想部分工作)

当项目较多时(需要滚动)

返回导致应用程序崩溃的空引用

我怀疑我用了错误的方法来看待问题。我应该使用一些与viewholder相关的东西,我实际上有点困惑如何从viewholder获得您想要的视图

如果有人能分享任何有帮助的东西,那就太好了!
如果有人需要,我很乐意提供更多的信息,

您应该使用
findViewHolderForAdapterPosition


请记住,如果位置未设置(例如,超出边界或删除),它将返回null。

由于我没有足够的信誉点来评论@yigit的答案,我想我会给出一种方法,从RecyclerView中检索所有的视图持有者,而不管视图组中当前有什么。即使使用FindViewHolder for AdapterPosition和for LayoutPosition,我们仍然可以在RecyclerView中获得ViewHolder的空实例

为了避免这种情况,我们可以使用findViewHolderForItemId[1],并使用RecyclerView.adapter#getItemId(int位置)[2]在适配器中传递viewHolder的ID

for (int i = 0; i < mAdapter.getItemCount(); i++) {
    RecyclerView.ViewHolder holder = 
            mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(i));
}
for(int i=0;i

  • 在RecyclerView的LayoutManager上使用findFirstCompletelyVisibleItemPosition()和findLastVisibleItemPosition()方法来确定要查找的子项是否可见。如果它是可见的,那么您可以使用getChild(index)来获取该特定子对象的ViewHolder实例,它不会为null,否则它可能为null(如果子对象不在其中)。如果您的孩子不可见,您只需在特定的位置列表对象中进行更改,下次只要它可见,就会更新UI

    if (selectedPosition >= linearLayoutManager.findFirstVisibleItemPosition()
                        && selectedPosition <= linearLayoutManager.findLastVisibleItemPosition()){
                        linearLayoutManager.getChildAt(selectedPosition).setBackgroundResource(0);
                    }
    
    if(selectedPosition>=linearLayoutManager.findFirstVisibleItemPosition()
    
    &&selectedPosition我如何从该视图持有者访问任何视图,我可以更改布局并充气新视图吗?无论如何,我使用的是一个cardview,它在用户尝试删除某个项目时首先隐藏,仅显示,这样我就可以避免在尝试直接从recyclerView访问视图时造成的混乱。我认为这一个工作正常我会一直使用这个概念,直到我能正确地从recyclerView@yigit你能再详细一点吗?你说你“应该使用…”。这是预期的行为还是错误?(为什么?)。我认为RecyclerView本身就是一个可滚动的视图,所以如果你问我,这有点奇怪。RecyclerView代表一个可能很长的项目列表,包含几个视图(足以填满屏幕).GetChildAt是一种视图组方法,与适配器位置无关。因此,当RV显示100项适配器的项目20到30时,视图组中只有10个子项(0处的子项是适配器项目20等)。这就是RV提供适配器索引方法的原因。它将返回null,因为当您调用
    notifyDataSetChanged
    时,在进行另一个布局计算之前,所有视图都无效。这是一个有趣的答案。我试过了,发现findViewHolderForItemId(int)只需要一个int位置,而不是getItemId(int)的长度返回。非常好的解决方案,非常感谢!
    for (int i = 0; i < mAdapter.getItemCount(); i++) {
        RecyclerView.ViewHolder holder = 
                mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(i));
    }
    
    if (selectedPosition >= linearLayoutManager.findFirstVisibleItemPosition()
                        && selectedPosition <= linearLayoutManager.findLastVisibleItemPosition()){
                        linearLayoutManager.getChildAt(selectedPosition).setBackgroundResource(0);
                    }