当卡片不在视线范围内时,FindViewHolderForPosition返回null [英] FindViewHolderForPosition return null when card's not in vision

查看:158
本文介绍了当卡片不在视线范围内时,FindViewHolderForPosition返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将RecyclerView与CardView一起使用以显示卡片列表.每张卡都有2个linearLayout(标题为1,扩展为1,仅当按下卡时第二个才可见).

I'm using RecyclerView with CardView to display a list of Cards. Every card has 2 linearLayout (1 for the header, and 1 for the expand, the second one became visible only when the card is pressed).

当我修改卡的优先级时,卡将移动到列表的新位置(我将其在项目的数组"中的位置更改,然后调用adapter.notifyItemMoved(oldPosition,newPosition)),工作正常,我还调用了RecyclerView.scrollToPosition(newPosition)来显示列表中的新位置.

When I modify the priority of a card, the card is moved in a new position of the list (I change it's position in the "array" of item, and then call adapter.notifyItemMoved(oldPosition,newPosition) ) and it works, I also called RecyclerView.scrollToPosition(newPosition) to show the new position in the list.

现在是问题,我想在将卡移动到新位置后对其进行扩展,为此,我需要在卡内部设置linearLayout,它们位于可容纳卡的ViewHolder中.我正在尝试使用RecyclerView.findViewHolderAtPosition(newPosition),但仅当卡在"scrollTo"之前的位置可见时,它才返回ViewHolder;如果将卡从这些可见卡"中移出,则它始终返回null. (我还使用mRecyclerView.setItemViewCacheSize(myDataset.size())解决其他问题,所以即使没有清晰的视野,我也期待正确的ViewHolder)

Now the problem, I want to expand the card after I moved it in the new position and to do so I need the linearLayout inside the card, they are in the ViewHolder that hold the card. I'm trying to use RecyclerView.findViewHolderAtPosition(newPosition), but it returns the ViewHolder only if the card is visible where I was before the "scrollTo", if the card is moved out of these "visible cards" it returns always null. (I'm also using mRecyclerView.setItemViewCacheSize(myDataset.size()) to solve other problems so I was expecting the correct ViewHolder even when it's not in vision)

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应该足够),但有时没有它就无法工作.

mAdapter.notifyDataSetChanged() shouldn't be called (notifyItemMoved should be enough) but sometimes it doesn't work without it.

expandCard只是将linearLayout"expandable"的可见性设置为Visible,而另一个linearLayout"expandable"已经对Gone可见.

expandCard just set the visibility of the linearLayout "expandable" to Visible and the other linearLayout "expandable" already visible to Gone.

我该怎么做才能使其正常工作?我做错了吗? 我希望我已经以一种可理解的方式解释了这个问题.如果我需要更好地解释自己的工作方式,我总是在这里,谢谢您的帮助.

What can I do to make it works? I'm doing it completely wrong? I hope I have explained the problem in a comprehensible way. If i need to explain better how I'm doing something I'm always here, thanks for the help.

推荐答案

所以我解决了这个问题,我想的是错误的方式.

So I kinda resolved it, I was thinking in the wrong way.

您不应该像我一样尝试从外部"找到合适的ViewHolder,而当一个绑定是正确的绑定时,只需在OnBindViewHolder中扩展"它即可.

You shouldn't try to find the right ViewHolder from "outside" like I was doing, but just "expand" it in the OnBindViewHolder when the one binding is the right one.

在moveTask中,我曾经做过,但是我设置了要打开的卡的位置:

In the moveTask I do was I was doing before, but I set the position of the card to be opened:

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中检查我何时处于正确的位置:

and then in the adapter's onBindViewHolder I check when I'm in the right position:

@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",它也应该可以工作,但是如果没有它,它还会有其他奇怪的问题,因此,我暂时将其保留.

And like this it works fine. It should work even without the use of "setItemViewCacheSize", but it has other strange problems without it so for now I leave it.

这篇关于当卡片不在视线范围内时,FindViewHolderForPosition返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆