Android 当卡片';它不在视野中
我正在使用RecyclerView和CardView来显示卡片列表。每张卡有2个线性布局(1个用于页眉,1个用于展开,第二个仅在按下卡时可见) 当我修改一张卡的优先级时,该卡被移动到列表的一个新位置(我更改它在项的“数组”中的位置,然后调用adapter.notifyItemMoved(oldPosition,newPosition))并且它工作,我还调用了RecyclerView.scrollToPosition(newPosition)来显示列表中的新位置 现在的问题是,我想在将卡移动到新位置后展开卡,为此,我需要卡内的线性布局,它们位于固定卡的视图支架中。我正在尝试使用RecyclerView.findViewHolderAtPosition(newPosition),但它仅在卡片在“scrollTo”之前的位置可见时返回ViewHolder,如果将卡片移出这些“可见卡片”,它将始终返回null。 (我也在使用mRecyclerView.setItemViewCacheSize(myDataset.size())来解决其他问题,因此即使在vision中没有,我也希望找到正确的ViewHolder)Android 当卡片';它不在视野中,android,android-recyclerview,Android,Android Recyclerview,我正在使用RecyclerView和CardView来显示卡片列表。每张卡有2个线性布局(1个用于页眉,1个用于展开,第二个仅在按下卡时可见) 当我修改一张卡的优先级时,该卡被移动到列表的一个新位置(我更改它在项的“数组”中的位置,然后调用adapter.notifyItemMoved(oldPosition,newPosition))并且它工作,我还调用了RecyclerView.scrollToPosition(newPosition)来显示列表中的新位置 现在的问题是,我想在将卡移动到新位
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);
}
}