RecyclerView.getChild (index) показывает null, когда список прокручивается (индекс запутывается)

Я использую SwipeableRecyclerView для моего приложения android для включения swipes для моего recyclerView. RecyclerView содержит список cardViews.

Я пытался реализовать функцию отмены для карт, которые будут удалены при прокрутке влево (первый салфетки показывает отменить, следующий салфетки триггеры удалить)

Я пытаюсь следующий код (частично работает, я думаю)

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);

возвращает нулевую ссылку, которая вызывает сбой приложения.

Я сомневаюсь, что я использую неправильный метод для просмотра. Я должен использовать что-то связанное с viewholder, я на самом деле смущен тем, как получить вид, который вы хотите от viewholder.

Если кто-нибудь может поделиться чем-нибудь, что помогает, это будет здорово! Я буду рад предоставить больше информации, если кто-то хочет,

3 ответов


вы должны использовать findViewHolderForAdapterPosition. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)

имейте в виду, что он вернет null, если позиция не выложена (например, вне границ или удалена).


поскольку у меня недостаточно очков репутации, чтобы прокомментировать ответ @yigit, я подумал, что дам способ получить все держатели представлений из RecyclerView независимо от того, что в настоящее время находится в viewGroup. Даже с findViewHolderForAdapterPosition и ForLayoutPosition мы все еще можем получить нулевой экземпляр ViewHolder в RecyclerView.

чтобы обойти это, мы можем использовать findViewHolderForItemId[1] и передайте ID viewHolder в адаптере, используя RecyclerView.Адаптер#getItemId (int позиция)[2]

for (int i = 0; i < mAdapter.getItemCount(); i++) {
    RecyclerView.ViewHolder holder = 
            mRecyclerView.findViewHolderForItemId(mAdapter.getItemId(i));
}
  1. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForItemId(int)
  2. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#getItemId(int)

используйте методы findFirstCompletelyVisibleItemPosition() & findLastVisibleItemPosition() в LayoutManager вашего RecyclerView, чтобы узнать, что ребенок, которого вы ищете, виден или нет. Если он виден, вы можете использовать getChild (index) для получения экземпляра ViewHolder этого конкретного ребенка, и он не будет нулевым, иначе он может быть нулевым(если ребенок не находится в нем). Если ваш ребенок не виден, вы просто вносите изменения в свой конкретный объект списка позиций, в следующий раз, когда он будет быть видимым будет обновлен пользовательский интерфейс.

if (selectedPosition >= linearLayoutManager.findFirstVisibleItemPosition()
                    && selectedPosition <= linearLayoutManager.findLastVisibleItemPosition()){
                    linearLayoutManager.getChildAt(selectedPosition).setBackgroundResource(0);
                }