RecyclerView.getChild(index) 滚动列表时显示 null(索引变得混乱)
RecyclerView.getChild(index) shows null when list is scrolled (index gets messed up)
我一直在为我的 android 应用程序使用 SwipeableRecyclerView,以便为我的 recyclerView 启用滑动。 RecyclerView 包含一个 cardView 列表。
我正在尝试为向左滑动时将被删除的卡片实现撤消功能(第一次滑动显示撤消,下一次滑动触发删除)
我正在尝试以下代码(我想部分有效)
SwipeableRecyclerViewTouchListener srvTouchListner = new SwipeableRecyclerViewTouchListener(rvTimerList,
new SwipeableRecyclerViewTouchListener.SwipeListener(){
@Override
public boolean canSwipe(int i) {
return true;
}
@Override
public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] ints) {
for(int position : ints){
View view = recyclerView.getChildAt(position);
if (view.getTag(R.string.card_undo) == null) {
if(viewStack == null) {
saveToViewStack(position, view);
final ViewGroup viewGroup = (ViewGroup) view.findViewById(R.id.time_card2);
view.setTag(R.string.card_undo, "true");
viewGroup.addView(view.inflate(TimerSummary.this, R.layout.timeslot_card_undo, null));
}
} else {
Log.d(TAG, "Removing Item");
deleteTimeSlot(timerInstanceList.get(position));
Toast.makeText(TimerSummary.this, "Deleted!", Toast.LENGTH_SHORT).show();
timerInstanceList.remove(position);
finalSummaryAdapter.notifyItemRemoved(position);
}
}
finalSummaryAdapter.notifyDataSetChanged();
}
@Override
public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] ints) {
for (int position:ints){
View view = recyclerView.getChildAt(position);
if(view.getTag(R.string.card_undo) != null && view.getTag(R.string.card_undo).equals("true")){
viewStack = null;
recyclerView.setAdapter(finalSummaryAdapter);
}
}
}
});
当项目更多时(需要滚动)
View view = recyclerView.getChildAt(position);
returns 导致应用程序崩溃的空引用。
我怀疑我是不是用错了取景的方法。我应该使用与 viewholder 相关的东西,我实际上对如何从 viewholder 获得你想要的视图感到困惑。
如果有人可以分享任何有用的东西,那就太好了!
如果有人需要,我很乐意提供更多信息,
你应该使用 findViewHolderForAdapterPosition
。
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)
请记住,如果位置未布局(例如超出范围或已删除),它将 return 为 null。
由于我没有足够的信誉点来评论@yigit 的回答,我想我会提供一种方法来从 RecyclerView 中检索所有 viewHolder,而不管 viewGroup 中当前有什么。即使使用 findViewHolderForAdapterPosition 和 ForLayoutPosition,我们仍然可以在 RecyclerView 中获得 ViewHolder 的空实例。
为了避免这种情况,我们可以使用 findViewHolderForItemId[1] 并使用 RecyclerView.Adapter#getItemId(int position)[[ 在适配器中传递 viewHolder 的 ID =17=]2]
for (int i = 0; i < mAdapter.getItemCount(); i++) {
RecyclerView.ViewHolder holder =
mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(i));
}
在 RecyclerView 的 LayoutManager 上使用 findFirstCompletelyVisibleItemPosition() 和 findLastVisibleItemPosition() 方法来确定您正在寻找的 child 是否可见。如果可见,则可以使用 getChild(index) 获取特定 child 的 ViewHolder 实例,它不会为空,否则它可能为空(如果 child 不在其中) .如果您的 child 不可见,您只需在您的特定位置列表 object 中进行更改,下次只要它可见就会更新 UI。
if (selectedPosition >= linearLayoutManager.findFirstVisibleItemPosition()
&& selectedPosition <= linearLayoutManager.findLastVisibleItemPosition()){
linearLayoutManager.getChildAt(selectedPosition).setBackgroundResource(0);
}
我一直在为我的 android 应用程序使用 SwipeableRecyclerView,以便为我的 recyclerView 启用滑动。 RecyclerView 包含一个 cardView 列表。
我正在尝试为向左滑动时将被删除的卡片实现撤消功能(第一次滑动显示撤消,下一次滑动触发删除)
我正在尝试以下代码(我想部分有效)
SwipeableRecyclerViewTouchListener srvTouchListner = new SwipeableRecyclerViewTouchListener(rvTimerList,
new SwipeableRecyclerViewTouchListener.SwipeListener(){
@Override
public boolean canSwipe(int i) {
return true;
}
@Override
public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] ints) {
for(int position : ints){
View view = recyclerView.getChildAt(position);
if (view.getTag(R.string.card_undo) == null) {
if(viewStack == null) {
saveToViewStack(position, view);
final ViewGroup viewGroup = (ViewGroup) view.findViewById(R.id.time_card2);
view.setTag(R.string.card_undo, "true");
viewGroup.addView(view.inflate(TimerSummary.this, R.layout.timeslot_card_undo, null));
}
} else {
Log.d(TAG, "Removing Item");
deleteTimeSlot(timerInstanceList.get(position));
Toast.makeText(TimerSummary.this, "Deleted!", Toast.LENGTH_SHORT).show();
timerInstanceList.remove(position);
finalSummaryAdapter.notifyItemRemoved(position);
}
}
finalSummaryAdapter.notifyDataSetChanged();
}
@Override
public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] ints) {
for (int position:ints){
View view = recyclerView.getChildAt(position);
if(view.getTag(R.string.card_undo) != null && view.getTag(R.string.card_undo).equals("true")){
viewStack = null;
recyclerView.setAdapter(finalSummaryAdapter);
}
}
}
});
当项目更多时(需要滚动)
View view = recyclerView.getChildAt(position);
returns 导致应用程序崩溃的空引用。
我怀疑我是不是用错了取景的方法。我应该使用与 viewholder 相关的东西,我实际上对如何从 viewholder 获得你想要的视图感到困惑。
如果有人可以分享任何有用的东西,那就太好了! 如果有人需要,我很乐意提供更多信息,
你应该使用 findViewHolderForAdapterPosition
。
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)
请记住,如果位置未布局(例如超出范围或已删除),它将 return 为 null。
由于我没有足够的信誉点来评论@yigit 的回答,我想我会提供一种方法来从 RecyclerView 中检索所有 viewHolder,而不管 viewGroup 中当前有什么。即使使用 findViewHolderForAdapterPosition 和 ForLayoutPosition,我们仍然可以在 RecyclerView 中获得 ViewHolder 的空实例。
为了避免这种情况,我们可以使用 findViewHolderForItemId[1] 并使用 RecyclerView.Adapter#getItemId(int position)[[ 在适配器中传递 viewHolder 的 ID =17=]2]
for (int i = 0; i < mAdapter.getItemCount(); i++) {
RecyclerView.ViewHolder holder =
mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(i));
}
在 RecyclerView 的 LayoutManager 上使用 findFirstCompletelyVisibleItemPosition() 和 findLastVisibleItemPosition() 方法来确定您正在寻找的 child 是否可见。如果可见,则可以使用 getChild(index) 获取特定 child 的 ViewHolder 实例,它不会为空,否则它可能为空(如果 child 不在其中) .如果您的 child 不可见,您只需在您的特定位置列表 object 中进行更改,下次只要它可见就会更新 UI。
if (selectedPosition >= linearLayoutManager.findFirstVisibleItemPosition()
&& selectedPosition <= linearLayoutManager.findLastVisibleItemPosition()){
linearLayoutManager.getChildAt(selectedPosition).setBackgroundResource(0);
}