2017-04-14 6 views
0

Ich muss ein Trennzeichen nur zum absoluten ersten Element meiner Recyclingansicht hinzufügen.Dekorieren Sie nur das absolut erste Element von RecyclerView

Ich habe bereits How to selectively decorate RecyclerView items, und ich verstehe, dass

Die (OnDraw) -Methode zur Zeit alle untergeordneten Ansichten Schleifen über im RecyclerView auf dem Bildschirm sichtbar.

und mein Problem ist genau das. da es jedes Mal ausgeführt wird, wenn sich die Ansichten in der RecycleView ändern, auch wenn ich nur den ersten Gegenstand, finde und dekoriere, sobald ich nach unten scrolle, verschiebt sich die Dekoration zum aktuellen ersten Gegenstand.

In diesem Link erfolgt die Auswahl durch die Methode isDecorated, die die Instanz des ViewHolder des aktuellen Kindes betrachtet. Meine Vermutung ist, dass der Mann in Bezug auf die ViewHolder Art dekorieren wollte, das ist nicht mein Problem, da ich nur eine Art von Element in meinem RecyclerView haben

Das ist mein DividerItemDecoration.java

public class DividerItemDecoration extends RecyclerView.ItemDecoration { 
    private Drawable mDivider; 

    public DividerItemDecoration(Drawable divider) { 
     mDivider = divider; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     super.getItemOffsets(outRect, view, parent, state); 

    RecyclerView.ViewHolder holder = parent.getChildViewHolder(view); 
     if (parent.getChildAdapterPosition(view) == 1) { 
      outRect.top = outRect.top + mDivider.getIntrinsicHeight(); 
     } 
     return; 

    } 

    @Override 
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) { 
     int dividerLeft = parent.getPaddingLeft(); 
     int dividerRight = parent.getWidth() - parent.getPaddingRight(); 

     int childCount = parent.getChildCount(); 
     for (int i = 0; i < childCount - 1; i++) { 
      if(i==0){ 
       View child = parent.getChildAt(i); 

       RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); 

       int dividerTop = child.getBottom() + params.bottomMargin; 
       int dividerBottom = dividerTop + mDivider.getIntrinsicHeight(); 

       mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom); 
       mDivider.draw(canvas); 
      } 
     } 
    } 
} 

Bitte beachten Sie, dass Ich habe den ganzen Tag gesucht und konnte nur Beispiele und Gist finden, Dekorator zu jedem Element hinzufügen, um es basierend auf dem Typ selektiv hinzuzufügen, aber nichts wirklich mit der absoluten Position anzugehen. Auch bitte keine Bibliotheken wie https://github.com/yqritc/RecyclerView-FlexibleDivider, möchte ich lernen, nicht zu kopieren.

+0

Sie haben 'parent.getChildAdapterPosition()' Methode, so ziehen Sie Ihre "Teiler" innen 'onDraw' nur, wenn diese Methode gibt 1 – pskink

+0

Dank dieser tatsächlich funktioniert! Lustigerweise benutzte ich diese Methode in 'getItemOffset' und dachte nicht daran, sie in 'onDraw' wiederzuverwenden. Leider bekomme ich seltsame Artefakte, wenn ich die Aktivität wechsle (indem ich auf den Zeileneintrag klicke) und zurück gehe. Der Teiler bewegt sich leicht. Woher? – MaX

Antwort

-1

Sie können prüfen, ob es das erste Element ist, ist Hier ein Beispiel:

Gerade getItemViewType() implementieren, und kümmern sich um die Viewtype Parameter in onCreateViewHolder().

So tun Sie so etwas wie:

@Override 
public int getItemViewType(int position) { 
    if (position == 0) 
     return 1; 
    else 
     return 2; 
} 

dann in onCreateViewHolder Ihre verschiedenen Layout nach Ihren Viewtype aufzublasen.

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    if (viewType == 1) { 
     // inflate your first item layout & return that viewHolder 
    } else { 
     // inflate your other item layout & return that viewHolder 
    } 
} 
+0

Gibt es ein besseres Layout für das erste Element über den Adapter, als wenn ein Dekorator nur auf das erste Element in Bezug auf die Leistung angewendet wird? – MaX

+0

Für das, was ich gelernt habe, ist dieser Weg der effizienteste Weg. Ist nur eine if/else-Anweisung, und stattdessen das gleiche Layout zu verwenden, verwenden Sie ein anderes Layout für das erste Element. Und dieser Weg ist auch der mit weniger Code –

+0

Ok, ich mag diese Antwort und ich denke, dass ich meine App auf diese Weise implementieren werde. Vielen Dank! Irgendein Hinweis, um die (ziemlich schreckliche) Animation zu ändern, die von dem Wischen folgt, um das erste Element zu verwerfen, was dazu führt, dass das zweite Element verschwindet (ein großes Loch hinterlassend), dann wieder an der ersten Position mit dem neuen Layout erscheint, während alle anderen nach oben scrollen ? – MaX

Verwandte Themen