RecyclerView.getChild(index) показывает null, когда список прокручивается (индекс перепутался)
Я использую SwipeableRecyclerView для моего приложения Android для включения swipes для моего recyclerView. RecyclerView содержит список карт.
Я пытался реализовать функции отмены для карт, которые будут удалены при прокрутке влево (сначала проведите пальцем по экрану, отмените удаление, затем трижды удалите триггеры)
Я пытаюсь использовать следующий код (частично работающий, я думаю)
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);
возвращает нулевую ссылку, которая вызывает сбой приложения.
Я сомневаюсь, что я использую неправильный метод для просмотра. Я должен использовать что-то, связанное с зрителем, я действительно смущен тем, как получить представление, которое вы хотите от зрителя.
Если кто-то может поделиться всем, что помогает, это будет здорово!
Я буду рад предоставить любую информацию, если кто-то хочет ее,
Ответы
Ответ 1
Вы должны использовать findViewHolderForAdapterPosition
.
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)
Имейте в виду, что он вернет значение null, если позиция не выложена (например, вне границ или удалена).
Ответ 2
Так как у меня недостаточно очков репутации, чтобы комментировать ответ @yigit, я думал, что дам способ получить все viewHolders из RecyclerView, независимо от того, что сейчас находится в группе viewGroup. Даже с помощью findViewHolderForAdapterPosition и ForLayoutPosition мы все равно можем получить нулевой экземпляр ViewHolder в RecyclerView.
Чтобы обойти это, мы можем использовать findViewHolderForItemId [ 1] и передать идентификатор viewHolder в адаптер с помощью RecyclerView.Adapter # getItemId (int position) [ 2 ]
for (int i = 0; i < mAdapter.getItemCount(); i++) {
RecyclerView.ViewHolder holder =
mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(i));
}
Ответ 3
Используйте методы findFirstCompletelyVisibleItemPosition() и findLastVisibleItemPosition() в LayoutManager вашего RecyclerView, чтобы узнать, что ребенок, которого вы ищете, виден или нет. Если это видно, вы можете использовать getChild (index), чтобы получить экземпляр ViewHolder этого конкретного ребенка, и он не будет пустым, иначе он может быть пустым (если в нем нет ребенка). Если ваш ребенок не виден, вы просто вносите изменения в свою конкретную позицию. Объект списка, в следующий раз, когда он будет виден, будет обновлен интерфейс.
if (selectedPosition >= linearLayoutManager.findFirstVisibleItemPosition()
&& selectedPosition <= linearLayoutManager.findLastVisibleItemPosition()){
linearLayoutManager.getChildAt(selectedPosition).setBackgroundResource(0);
}