android - 当卡不在视野中时,FindViewHolderForPosition 返回 null

标签 android android-recyclerview

我将 RecyclerView 与 CardView 结合使用来显示卡片列表。每张卡片都有 2 个 linearLayout(1 个用于标题,1 个用于扩展,第二个仅在卡片被按下时才可见)。

当我修改卡片的优先级时,卡片会移动到列表的新位置(我更改它在项目“数组”中的位置,然后调用 adapter.notifyItemMoved(oldPosition,newPosition) )并且它有效,我还调用了 RecyclerView.scrollToPosition(newPosition) 来显示列表中的新位置。

现在的问题是,我想在将卡片移动到新位置后展开它,为此我需要卡片内的 linearLayout,它们位于容纳卡片的 ViewHolder 中。我正在尝试使用 RecyclerView.findViewHolderAtPosition(newPosition),但只有当卡片在“scrollTo”之前的位置可见时,它才会返回 ViewHolder,如果卡片从这些“可见卡片”中移出,它始终返回 null。 (我还使用 mRecyclerView.setItemViewCacheSize(myDataset.size()) 来解决其他问题,所以我期待正确的 ViewHolder,即使它不在视野中)

public void moveTask(int oldPosition, int position, Task task) {
    if (oldPosition < position) {
        myDataset.add(position, task);
        myDataset.remove(oldPosition);
    } else {
        myDataset.remove(oldPosition);
        myDataset.add(position, task);
    }
    mAdapter.notifyItemMoved(oldPosition, position);
    mAdapter.notifyDataSetChanged();
    mRecyclerView.smoothScrollToPosition(position);
    MyViewHolder holder =(MyViewHolder)mRecyclerView.findViewHolderForPosition(position);
    mAdapter.expandCard(holder);
}

mAdapter.notifyDataSetChanged() 不应被调用(notifyItemMoved 应该足够了)但有时没有它就无法工作。

expandCard 只是将 linearLayout“expandable”的可见性设置为 Visible,而另一个 linearLayout“expandable”已经可见到 Gone。

我该怎么做才能让它发挥作用?我做的完全错了吗? 我希望我已经以一种易于理解的方式解释了这个问题。如果我需要更好地解释我是如何做某事的,我总是在这里,感谢您的帮助。

最佳答案

所以我有点解决了,我的想法是错误的。

您不应该像我一样尝试从“外部”找到正确的 ViewHolder,而是当一个绑定(bind)是正确的绑定(bind)时在 OnBindViewHolder 中“扩展”它。

在我做的moveTask中是我之前做的,但是我设置了要打开的卡的位置:

public void moveTask(int oldPosition, int position, Task task) {
    if (oldPosition < position) {
        myDataset.add(position, task);
        myDataset.remove(oldPosition);
    } else {
        myDataset.remove(oldPosition);
        myDataset.add(position, task);
    }
    mAdapter.notifyItemMoved(oldPosition, position);
    //this is the important line, it set the variable
    //openPos with the right number
    mAdapter.setOpenPos(position);

    mAdapter.notifyItemChanged(position);
    mRecyclerView.scrollToPosition(position);
}

然后在适配器的 onBindViewHolder 中检查我是否处于正确的位置:

@Override
public void onBindViewHolder(MyViewHolder holder, int pos) {
    --set other fields--
    // expand the right card
    // if it's the first open it
    if (pos == 0) {
        holder.expand(holder.mHeader, holder.mExpanded);
        // and collapse the opened one
        if (openPos != -1 && openPos != pos) {
            open.collapse(open.mHeader, open.mExpanded, true);
        }
        isFirst = holder;
        open = holder;
        openPos = 0;
    } 
     // I'm in the position of the one I should open
     // expand it
     else if (openPos != -1 && pos == openPos) {
        holder.expand(holder.mHeader, holder.mExpanded);
        // and if I changed openPos with setOpenPos()
        // collapse the "old" open card
        if(openPos != open.getPosition()){
            open.collapse(open.mHeader, open.mExpanded, true);
        }
        open = holder;
    }
     // if I'm in another card just collapse it 
     else {
        holder.collapse(holder.mHeader, holder.mExpanded, true);
    }

}

像这样它工作正常。即使不使用“setItemViewCacheSize”它也应该可以工作,但是没有它它还有其他奇怪的问题所以现在我离开它。

关于android - 当卡不在视野中时,FindViewHolderForPosition 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27603015/

相关文章:

Android 自定义字体 - 适用于 Actionbar、Toast、Dialogs 等系统组件

android - 使我的文本的特定部分可点击

Android:使用触摸框架处理回收者 View 项内 ImageView 的点击

android - 多个 RecyclerView 的同步滚动

java - 在我的自定义 Listview Android ==> 空指针异常..?

Android:拖动多个 View

android - textView 不显示输出

android - 有什么方法可以使用 cursoradapter 在 recyclerview 中实现字母部分索引?

android - ConstraintLayout 中的 RecyclerView 与其他元素重叠

java - 如何按照 API 调用完成的顺序在 RecyclerView 中加载项目?