Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 当卡片';它不在视野中_Android_Android Recyclerview - Fatal编程技术网

Android 当卡片';它不在视野中

Android 当卡片';它不在视野中,android,android-recyclerview,Android,Android Recyclerview,我正在使用RecyclerView和CardView来显示卡片列表。每张卡有2个线性布局(1个用于页眉,1个用于展开,第二个仅在按下卡时可见) 当我修改一张卡的优先级时,该卡被移动到列表的一个新位置(我更改它在项的“数组”中的位置,然后调用adapter.notifyItemMoved(oldPosition,newPosition))并且它工作,我还调用了RecyclerView.scrollToPosition(newPosition)来显示列表中的新位置 现在的问题是,我想在将卡移动到新位

我正在使用RecyclerView和CardView来显示卡片列表。每张卡有2个线性布局(1个用于页眉,1个用于展开,第二个仅在按下卡时可见)

当我修改一张卡的优先级时,该卡被移动到列表的一个新位置(我更改它在项的“数组”中的位置,然后调用adapter.notifyItemMoved(oldPosition,newPosition))并且它工作,我还调用了RecyclerView.scrollToPosition(newPosition)来显示列表中的新位置

现在的问题是,我想在将卡移动到新位置后展开卡,为此,我需要卡内的线性布局,它们位于固定卡的视图支架中。我正在尝试使用RecyclerView.findViewHolderAtPosition(newPosition),但它仅在卡片在“scrollTo”之前的位置可见时返回ViewHolder,如果将卡片移出这些“可见卡片”,它将始终返回null。 (我也在使用mRecyclerView.setItemViewCacheSize(myDataset.size())来解决其他问题,因此即使在vision中没有,我也希望找到正确的ViewHolder)

public void moveTask(int-oldPosition,int-position,Task-Task){
如果(旧位置<位置){
添加(职位、任务);
myDataset.remove(oldPosition);
}否则{
myDataset.remove(oldPosition);
添加(职位、任务);
}
mAdapter.notifyItemMoved(旧位置,位置);
mAdapter.notifyDataSetChanged();
mRecyclerView.smoothScrollToPosition(位置);
MyViewHolder=(MyViewHolder)mRecyclerView.FindViewHolder for position(position);
mAdapter.expandCard(持有者);
}
不应调用mAdapter.notifyDataSetChanged()(notifyItemMoved应该足够了),但有时如果没有它,它将无法工作

expandCard只需将linearLayout“expandable”的可见性设置为Visible,将另一个linearLayout“expandable”的可见性设置为Gone

我能做些什么使它工作?我完全错了?
我希望我已经以一种可以理解的方式解释了这个问题。如果我需要更好地解释我在做什么,我总是在这里,谢谢你的帮助。

首先,你不应该调用
mRecyclerView.setItemViewCacheSize(myDataset.size())
。这意味着为列表中的每个项目创建一个ViewHolder,与使用LinearLayout没有太大区别

其次,
findViewHolderForPosition
只检查孩子。这将添加到文档中以进行澄清

在您的情况下,
mAdapter.notifyItemMoved
不够,因为RV不知道必须重新绑定项目。您还需要调用
notifyItemChanged
,以便RV知道应该恢复视图

创建两种视图类型(为了简单起见,您不必这样做)。一个坍塌,一个膨胀。然后,如果要移动和展开项目,请调用:

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);
    }
    task.expanded = true;
    mAdapter.notifyItemMoved(oldPosition, position);
    mAdapter.notifyItemChanged(position);
}

//adapter
getItemViewType(int position) {
    return myDataset.get(position).expanded ? TYPE_EXPANDED : TYPE_HEADER;
}
public void moveTask(int-oldPosition,int-position,Task-Task){
如果(旧位置<位置){
添加(职位、任务);
myDataset.remove(oldPosition);
}否则{
myDataset.remove(oldPosition);
添加(职位、任务);
}
task.expanded=true;
mAdapter.notifyItemMoved(旧位置,位置);
mAdapter.notifyItemChanged(位置);
}
//适配器
getItemViewType(int位置){
返回myDataset.get(position).expanded?TYPE\u expanded:TYPE\u HEADER;
}

因为您调用了notifyItemChangedRV将重新绑定该视图。

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

您不应该像我那样尝试从“外部”找到正确的视图持有者,而应该在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);
}

就像这样,它工作得很好。即使不使用“setItemViewCacheSize”,它也应该可以工作,但是如果没有它,它还有其他奇怪的问题,所以现在我不使用它。

我知道我不应该调用setItemViewCacheSize,但是如果没有它,我们会遇到一些奇怪的问题,例如,如果我展开第一张卡并向下滚动,第12张卡(在我的手机中,第14张卡在另一部手机中)也扩大了。我不确定如何使用您建议的两种视图类型,因为我正在使用动画制作转换动画:private void expand(LinearLayout标头,RelativeLayout expanded){expanded.setVisibility(view.VISIBLE);…ValueAnimator animator=slideAnimator(header.getMeasuredHeight(),expanded.getMeasuredHeight(),expanded);animator.start();}我遇到了完全相同的情况。
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);
}
@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);
    }

}