2017-09-14 4 views
5

Ich habe eine ganz einfache RecyclerView. Dies ist, wie ich den Teiler gesetztRecyclerView entfernen Teiler/Dekorateur nach dem letzten Artikel

DividerItemDecoration itemDecorator = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL); 
itemDecorator.setDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.news_divider)); 
recyclerView.addItemDecoration(itemDecorator); 

Und das ist ziehbar/news_divider.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <solid android:color="@color/white_two"/> 
    <size android:height="1dp"/> 
</shape> 

Das Problem für einigen dummen Grund ist der Teiler nicht nur zwischen den Elementen erzeugt wird. Aber auch nach dem letzten Gegenstand. Und ich will es nur zwischen den Gegenständen nicht nach jedem Gegenstand.

Haben Sie eine Idee, wie Sie verhindern können, dass der Teiler nach dem letzten Gegenstand angezeigt wird?

Beifall und Dank

+1

Verwenden Sie nicht den Standard-Teiler. Sie fügen den Teiler in Ihrem Xml-Element für die Recycleransicht hinzu und zeigen oder verbergen die Basis nach Bedarf. – james

+0

poste deinen Teiler-Dekorateur-Code. –

Antwort

12

Versuchen Sie diesen Code, es wird keine Teiler für den letzten Artikel angezeigt.

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

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

    @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 - 2; i++) { 
      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); 
     } 
    } 
} 

divider.xml:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <size 
     android:width="1dp" 
     android:height="1dp" /> 
    <solid android:color="@color/grey_300" /> 
</shape> 

Stellen Sie Ihren Divider wie folgt aus:

RecyclerView.ItemDecoration dividerItemDecoration = new DividerItemDecorator(ContextCompat.getDrawable(context, R.drawable.divider)); 
recyclerView.addItemDecoration(dividerItemDecoration); 
+3

Upvoted, sollte es aber auch nicht sein ** i <= childCount - 2 ** oder ** i

+0

Wenn Sie keinen Teiler für den letzten Artikel zeichnen möchten, müssen Sie einen davon setzen. –

+0

yeah aber du hast geschrieben ** ich

1

Erstellen Sie Ihre eigenen Divider Klasse (Example here)

In dem Code, der die Trennlinie zieht, überprüfen Sie zuerst, wenn Sie den Teiler für das letzte Element in der Liste zeichnen. Wenn ja, zeichne es nicht.

Seien Sie sich bewusst, dass wenn Sie OnDrawOver überschreiben, es auf der Oberseite Ihrer Ansicht einschließlich Scrollbars usw. zieht. Am besten, um an OnDraw zu bleiben. Viele Beispiele auf Google, aber this ist ein gutes Tutorial zum Erstellen Ihrer eigenen Dekorateure.

+0

Yeap, onDrawOver lieferte auf einigen Geräten fehlerhafte Ergebnisse. –

1

Hier ist die DividerDecorator Klasse, die ich in meinen Apps verwende, die die unterste Zeile des letzten Elements entfernt.

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

    public DividerDecorator(Context context) { 
     mDivider = context.getResources().getDrawable(R.drawable.recyclerview_divider); 
    } 

    @Override 
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 
     int left = parent.getPaddingLeft(); 
     int right = parent.getWidth() - parent.getPaddingRight(); 

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

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

      int top = child.getBottom() + params.bottomMargin; 
      int bottom = top + mDivider.getIntrinsicHeight(); 

      mDivider.setBounds(left, top, right, bottom); 
      mDivider.draw(c); 
     } 
    } 
} 

Sie können es auf Ihre RecyclerView mit dem folgenden Code ein:

mRecyclerViewEvent.addItemDecoration(new DividerDecorator(context)); 

Hier ist der recyclerview_divider.xml

<size 
    android:width="1dp" 
    android:height="1dp" /> 

<solid android:color="@color/DividerColor" /> 

+0

Ich habe Sie updated, aber überschreiben OnDrawOver lieferte unerwünschte Ergebnisse. der Teiler verhält sich ständig falsch. Der OnDraw-Override erwies sich als besser für mich. –

9

Als here vorgeschlagen Sie DividerItemDecoration wie folgt erweitern können:

recyclerView.addItemDecoration(
    new DividerItemDecoration(context, layoutManager.getOrientation())) { 
     @Override 
     public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
      int position = parent.getChildAdapterPosition(view); 
      // hide the divider for the last child 
      if (position == parent.getAdapter().getItemCount() - 1) { 
       outRect.setEmpty(); 
      } else { 
       super.getItemOffsets(outRect, view, parent, state); 
      } 
     } 
    } 

);

+0

Schöne und saubere Idee, aber ich mochte onDraw Overriding besser, da dies nicht wirklich so war, wie ich in der äußeren Klasse wollte. –

+0

Dieser Code wird nicht kompiliert. – David

+1

Diese Lösung ist sauberer als die akzeptierte Lösung, da sie auf der Adapterposition und nicht auf dem untergeordneten Index beruht. Um sie auch wieder verwendbar zu machen, ersetzen Sie anonyme innere Klassen durch öffentliche Unterklassen, z. 'public class MiddleDividerItemDecoration erweitert DividerItemDecoration {...'. –

0

Sie können RecyclerView.ItemDecoration verlängern und onDraw und getItemOffsets übersteuern.

Verwenden Sie DividerItemDecoration als Referenz und kopieren Sie über das Wesentliche in Ihre eigene Klasse.

Wenn Sie dies tun, werden Sie mit etwas so enden:

public class SimpleDividerDecoration extends RecyclerView.ItemDecoration { 

    private Drawable divider; 

    private final Rect bounds = new Rect(); 

    public SimpleDividerDecoration(Drawable divider) { 
     this.divider = divider; 
    } 

    @Override 
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) { 
     final int left = 0; 
     final int right = parent.getWidth(); 
     final int childCount = parent.getChildCount() - 1; 
     for (int i = 0; i < childCount; i++) { 
      final View child = parent.getChildAt(i); 
      parent.getDecoratedBoundsWithMargins(child, bounds); 
      final int bottom = bounds.bottom + Math.round(child.getTranslationY()); 
      final int top = bottom - divider.getIntrinsicHeight(); 
      divider.setBounds(left, top, right, bottom); 
      divider.draw(canvas); 
     } 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     final int position = parent.getChildAdapterPosition(view); 
     final int lastPosition = parent.getAdapter().getItemCount() - 1; 
     if (position < lastPosition) { 
      outRect.set(0, 0, 0, divider.getIntrinsicHeight()); 
     } 
    } 
} 

Wenn Sie dies vergleichen mit DividerItemDecoration, werden Sie feststellen, dass es Unterstützung für horizontale Layouts entfernt. Außerdem können Sie eine drawable direkt an den Konstruktor übergeben.


Die - 1 Sie in beiden Verfahren sehen zum Entfernen des letzten Teiler verantwortlich:

  1. Es verhindert onDraw aus den letzten Teiler zeichnen.
  2. Es verhindert getItemOffsets Platz (Pixel) für den letzten Teiler zu besetzen.

EXPERIMENT

  • - 1 von getItemOffsets, entfernen, aber es in onDraw verlassen.
  • Aktivieren Sie "Layoutgrenzen anzeigen" in den Entwickleroptionen auf Ihrem Telefon .
  • Stellen Sie Ihre Teiler Höhe etwas groß wie 20dp

Wenn Sie Ihr Projekt jetzt laufen, werden Sie feststellen, dass, obwohl der letzte Teiler nicht gezogen wird, noch Platz für sie vorgesehen ist.

Verwandte Themen