2016-07-14 5 views
0

Unten ist, wie ich den Abstand für RecyclerView-Elemente mache. Es wurde entwickelt, um mit Grids und Listen zu arbeiten. Der Abstand funktioniert.RecyclerView ItemDecoration: Abstand und Dividierer

Was ich nicht herausfinden kann, ist, wie man eine Trennlinie auch einfügt. Jede Hilfe wird sehr geschätzt.

SIDE HINWEIS:, wenn Sie einen besseren Weg, den Abstand zu implementieren als das, was ich gerade tun, würde ich auch sehr dankbar :)

public class ItemOffsetDecoration extends RecyclerView.ItemDecoration { 

    private int numOfColumns; 
    private int listSize; 
    private int offsetInDp; 
    private boolean isGridView; 
    private boolean canScrollHorizontally; 
    private boolean isBottomRow = false; 


    public ItemOffsetDecoration(RecyclerView.LayoutManager manager, int listSize, int offsetInDp) { 
     this(manager, 1, listSize, offsetInDp); 
    } 

    public ItemOffsetDecoration(RecyclerView.LayoutManager manager, int numOfColumns, int listSize, int offsetInDp) { 
     this.numOfColumns = numOfColumns; 
     this.listSize = listSize; 
     this.offsetInDp = PixelConversionUtils.dpToPx(offsetInDp); 

     this.isGridView = manager instanceof GridLayoutManager; 
     this.canScrollHorizontally = manager.canScrollHorizontally(); 
    } 

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

     // only do left/right spacing if grid or horizontal list 
     if (isGridView || canScrollHorizontally) { 
      outRect.left = offsetInDp; 
      outRect.right = offsetInDp; 
     } 

     // only do top/bottom spacing if grid or vertical list 
     if (isGridView || !canScrollHorizontally) { 
      int pos = parent.getChildAdapterPosition(view); 
      boolean isNotTopRow = pos >= numOfColumns; 

      // Don't add top spacing to top row 
      if (isNotTopRow) { 
       outRect.top = offsetInDp; 
      } 

      int columnIndex = ((GridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex(); 

      if (pos >= (listSize - numOfColumns) && columnIndex == 0) { 
       isBottomRow = true; 
      } 

      // Don't add bottom spacing to bottom row 
      if (!isBottomRow && pos < (listSize - numOfColumns)) { 
       outRect.bottom = offsetInDp; 
      } 
     } 
    } 
} 

hier eine schnelle visuelle ist von dem, was ich bin auf der Suche zu tun:

hier ist, was ich habe:

enter image description here

hier ist, was ich will :

enter image description here

+0

Können Sie den Screenshot einfügen, was Sie erwarten?Ist es nicht genug, nur ein Paar zu haben: RecyclerView & CardView? – Silwester

+0

erledigt. Werfen Sie einen Blick auf – Psest328

+0

override 'onDraw' /' onDrawOver' dann – pskink

Antwort

1

Sie können auf diese Weise gewünschtes Aussehen erreichen:

  • ersten, erstellen Sie einen Teiler Drawable, in diesem Beispiel habe ich eine einfache Form verwendet, aber man kann Standardlinienteiler oder andere ziehbar verwenden:

    <shape xmlns:android="http://schemas.android.com/apk/res/android" 
        android:shape="rectangle"> 
        <size android:height="2dp" /> 
        <size android:width="2dp" /> 
        <solid android:color="#000000" /> 
    </shape> 
    
  • Sekunde, in Ihrem ItemOffsetDecoration Drawable deklarieren und initialisieren:

    public class ItemOffsetDecoration extends RecyclerView.ItemDecoration { 
    
        private Drawable mDivider; 
    
        ... 
    
        public ItemOffsetDecoration(...) { 
         mDivider = ContextCompat.getDrawable(context, R.drawable.item_divider); 
        } 
    } 
    
  • dritte, außer Kraft setzen onDrawOver() Methode:

    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 
        if (isGridView) { 
         drawVerticalDivider(c, parent); 
        } else { 
         drawVerticalDivider(c, parent); 
         drawHorizontalDivider(c, parent); 
        } 
    
    } 
    

    wo drawVerticalDivider() & drawHorizontalDivider() sind (vielleicht eine gute Idee sein, um sie in die Betriebsverfahren und die Richtung des Teilers über Parametersteuerung zu Umgestalten):

    public void drawVerticalDivider(Canvas c, RecyclerView parent) { 
        if (parent.getChildCount() == 0) return; 
    
        final int childCount = parent.getChildCount(); 
    
        for (int i = 0; i < childCount; i++) { 
         View child = parent.getChildAt(i); 
         RecyclerView.LayoutParams params = 
           (RecyclerView.LayoutParams) child.getLayoutParams(); 
    
         int left = child.getLeft() - params.leftMargin - offsetInDp; 
         int right = child.getRight() + params.rightMargin + offsetInDp; 
         int top = child.getBottom() + params.bottomMargin + offsetInDp; 
         int bottom = top + mDivider.getIntrinsicHeight(); 
         mDivider.setBounds(left, top, right, bottom); 
         mDivider.draw(c); 
        } 
    } 
    
    public void drawHorizontalDivider(Canvas c, RecyclerView parent) { 
        final int childCount = parent.getChildCount(); 
    
        for (int i = 0; i < childCount; i++) { 
         View child = parent.getChildAt(i); 
         RecyclerView.LayoutParams params = 
           (RecyclerView.LayoutParams) child.getLayoutParams(); 
    
         int left = child.getRight() + params.rightMargin + offsetInDp; 
         int right = left + mDivider.getIntrinsicWidth(); 
         int top = child.getTop() - params.topMargin - offsetInDp; 
         int bottom = child.getBottom() + params.bottomMargin + offsetInDp; 
         mDivider.setBounds(left, top, right, bottom); 
         mDivider.draw(c); 
        } 
    } 
    

Ergebnis für den linearen und Grid LayoutManagers:

LinearLayoutManagerGridLayoutManager

+0

das hat wunderbar funktioniert. Frage: Wie würde ich die Dicke der Trennwände einstellen? – Psest328

+0

auch ... fand ein kleines Problem, auf das mein Chef springen wird. An jeder Kreuzung wird kein Teiler gezeichnet. Hier ist ein Screenshot, der wirklich klein ist, also hoffe ich es zeigt ... http://imgur.com/c3ehjmp – Psest328

+0

@WizardKnight Wenn Sie Shape von meinem Beispiel verwendet haben, dann müssen Sie 'Größe' Tag des Drawable bearbeiten '2dp' auf den gewünschten Wert. Was ist mit dem zweiten Problem, es kann passieren, weil Sie den Wert der Variable 'offsetInDp' zu berechnen, habe ich einen vordefinierten Wert verwendet, um Offsets für dieses Beispiel zu setzen, und ich habe keinen solchen leeren Punkt. – Artem

0

haha ​​...... actualy hatte, ich für Divider wie diese versuchen, wenn auch mit ein bisschen komisch: zuerst Sie recycleview backgroud mit dunkler Farbe machen, und item_view backgroud weiß, dann für jedes Element Margin machen - > ich bin ernst, nicht überstimmen :)

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<LinearLayout 
    android:orientation="horizontal" 
    android:layout_width="match_parent" 
    android:layout_marginBottom="2dp" 
    android:layout_height="wrap_content"> 

    <TextView 
     android:layout_weight="1" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" /> 

    <TextView 
     android:layout_weight="1" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" /> 

</LinearLayout> 

0

Versuchen Sie das folgende XML-snippet platzieren einen Teiler zu erhalten:

<View android:layout_width="match_parent" 
     android:layout_height="1dp" 
     android:layout_marginLeft="72dp" 
     android:layout_marginRight="16dp" 
     android:background="123e4152"/> 

Sie können dies im RecyclerView-Artikellayout unter Ihren Artikeln einfügen. Spielen Sie auch mit den Rändern und dem Hintergrund, um Ihrer Liste zu entsprechen.

Verwandte Themen