2015-06-16 9 views
11

Ich habe SwipeableRecyclerView für meine Android-Anwendung verwendet, um Swipes für meine RecyclerView zu aktivieren. RecyclerView enthält eine Liste von cardViews.RecyclerView.getChild (Index) zeigt Null, wenn die Liste gescrollt wird (Index wird durcheinander gebracht)

Ich habe versucht, Undo-Funktionalität für Karten zu implementieren, die gelöscht werden, wenn Swipe (erste Swipe zeigt rückgängig zu machen, neben Swipe löst löschen) nach links

Ich versuche, den folgenden Code (teilweise arbeiten I guess)

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

       } 
      }); 

wenn Einzelteile sind mehr (Bedürfnisse Scrollen)

View view = recyclerView.getChildAt(position); 

gibt eine null-Referenz, die eine App Absturz verursacht.

Ich bezweifle, dass ich die falsche Methode zur Ansicht verwende. Ich sollte etwas verwenden, das mit Viewholder verwandt ist, ich bin wirklich irgendwie verwirrt darüber, wie man die Ansicht bekommt, die man vom Viewholder will.

Wenn jemand etwas teilen kann, das hilft ,, das wird großartig! Ich werde glücklich sein, mehr Infos zur Verfügung zu stellen, wenn jemand es wünscht,

Antwort

17

Sie sollten findViewHolderForAdapterPosition verwenden. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#findViewHolderForAdapterPosition(int)

Denken Sie daran, dass es Null zurückgibt, wenn die Position nicht ausgelegt ist (z. B. außerhalb der Grenzen oder entfernt).

+1

Wie greife ich auf Ansichten dieses Viewholders zu? Kann ich das Layout ändern und ein neues aufblasen? –

+0

Wie auch immer, ich benutze ein cardview, das zuerst nur angezeigt wird, wenn der Benutzer versucht, ein Element zu löschen. Auf diese Weise kann ich aus dem Chaos entkommen, das entsteht, wenn ich versuche, direkt von recyclerView auf die Ansichten zuzugreifen.Dieses funktioniert gut, ich werde dieses Konzept verwenden, bis ich in der Lage bin, Ansichten von recyclerView –

+0

@yigit properly nehmen Können Sie ein bisschen mehr erarbeiten? Du hast gesagt, du solltest "..." benutzen. Ist dies das erwartete Verhalten oder ein Fehler? (Warum?). Ich sehe RecyclerView als scrollbare Ansicht, daher ist das ein bisschen komisch, wenn Sie mich fragen. – GMan

8

Da ich nicht genug Reputationspunkte habe, um @ yigits Antwort zu kommentieren, dachte ich, ich würde einen Weg finden, alle viewHolder aus einem RecyclerView abzurufen, unabhängig davon, was gerade in der viewGroup ist. Selbst mit findViewHolderForAdapterPosition und ForLayoutPosition können wir immer noch eine Null-Instanz des ViewHolders in der RecyclerView erhalten.

dies zu umgehen, kann man verwenden findViewHolderForItemId [ 1] und die ID des viewHolder in dem Adapter übergeben unter Verwendung RecyclerView.Adapter # GetItemID (int position) []

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

Dies ist eine interessante Antwort. Ich habe es versucht und festgestellt, dass findViewHolderForItemId (int) will nur eine int-Position, nicht die Long, die getItemId (int) zurückgibt. – Gi0rgi0s

0

Verwenden Sie f indFirstCompletelyVisibleItemPosition() & findLastVisibleItemPosition() -Methoden auf dem LayoutManager von RecyclerView, um herauszufinden, ob das Kind, nach dem Sie suchen, sichtbar ist oder nicht. Wenn es sichtbar ist, können Sie getChild (index) verwenden, um die ViewHolder-Instanz dieses bestimmten untergeordneten Elements abzurufen, und es wäre nicht null, andernfalls könnte es null sein (wenn das untergeordnete Element nicht darin enthalten ist). Falls Ihr Kind nicht sichtbar ist, nehmen Sie einfach Änderungen an Ihrer spezifischen Position vor. Wenn das nächste Mal das Objekt sichtbar ist, wird es eine aktualisierte Benutzeroberfläche haben.

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