2015-06-16 13 views
11

Używam SwipeableRecyclerView dla mojej aplikacji Android do włączania suwaków dla mojego recyclerView. RecyclerView zawiera listę cardViews.RecyclerView.getChild (indeks) pokazuje wartość null podczas przewijania listy (indeks zostaje pomieszany)

starałem się wdrożyć funkcjonalność cofania dla kart które zostaną usunięte, gdy przesunięcie w lewo (pokazy pierwszy swipe cofnąć, obok machnięcia powoduje usunięcie)

próbuję następujący kod (częściowo działa chyba)

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

       } 
      }); 

gdy przedmioty są bardziej (potrzeby przewijania)

View view = recyclerView.getChildAt(position); 

zwraca pustą referencję, która powoduje awarii aplikacji.

Wątpię, czy używam niewłaściwej metody widzenia. Powinienem używać czegoś związanego z widownią, jestem w pewnym sensie niejasny, jak uzyskać pogląd, który chcesz od widza.

Jeśli ktokolwiek może udostępnić coś, co pomaga ,, to będzie świetnie! Z przyjemnością udzielę dalszych informacji, jeśli ktoś będzie chciał,

Odpowiedz

17

Powinieneś użyć findViewHolderForAdapterPosition. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)

Należy pamiętać, że zwróci wartość null, jeśli pozycja nie jest określona (na przykład poza zakresem lub usunięta).

+1

W jaki sposób mogę uzyskać dostęp do widoków z tego widoku, Czy mogę zmienić układ i nadmuchać nowy? –

+0

W każdym razie używam cardview, który jest najpierw ukryty, aby pokazać się, kiedy użytkownik próbuje usunąć przedmiot, W ten sposób mogę uciec od bałaganu utworzonego, gdy próbuję uzyskać dostęp do widoków bezpośrednio z recyclerView.Ten działa dobrze, będę używał tej koncepcji, dopóki nie będę w stanie robić poglądów prooperly z recyclerView –

+0

@yigit Czy możesz rozwinąć nieco więcej? Powiedziałeś, że "powinieneś użyć ...". Czy jest to oczekiwane zachowanie lub błąd? (czemu?). Widzę RecyclerView jako widok przewijany sam, więc to trochę dziwne, jeśli mnie pytasz. – GMan

8

Ponieważ nie mam wystarczającej liczby punktów reputacji, aby skomentować odpowiedź @ yigit, pomyślałem, że dałbym sposób na odzyskanie wszystkich viewHolders z RecyclerView niezależnie od tego, co aktualnie znajduje się w viewGroup. Nawet z findViewHolderForAdapterPosition i ForLayoutPosition nadal możemy uzyskać zerową instancję ViewHolder w RecyclerView.

Aby to obejść, można użyć findViewHolderForItemId [] i przekazać identyfikator viewHolder w karty przy użyciu RecyclerView.Adapter # getItemId (int pozycja) []

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)
+0

To jest interesująca odpowiedź. Próbowałem go i okazało się, że findViewHolderForItemId (int) po prostu chce pozycji int, a nie Long, że getItemId (int) zwraca. – Gi0rgi0s

0

Zastosowanie f indFirstCompletelyVisibleItemPosition() & findLastVisibleItemPosition() metody w Menedżerze układu z Twojego Recyklingu, aby sprawdzić, czy dziecko, którego szukasz, jest widoczne, czy nie. Jeśli jest widoczny, możesz użyć metody getChild (index), aby uzyskać instancję ViewHolder tego konkretnego dziecka i nie będzie to wartość NULL, ponieważ może to być wartość pusta (jeśli nie ma w niej dziecka). Jeśli twoje dziecko nie jest widoczne, po prostu wprowadzasz zmiany w swojej konkretnej pozycji Obiekt listy, następnym razem, gdy będzie widoczny, będzie zaktualizowany interfejs użytkownika.

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