2017-09-14 144 views
5

我有一個相當簡單的RecyclerView。 這是我設置分頻器RecyclerView刪除最後一個項目後的分隔器/裝飾器

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

這是繪製/ 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> 

的問題是分隔不只是在項目之間創造了一些愚蠢的原因。但也是在最後一個項目之後。而且我只希望它之間的物品之間沒有每件物品。

任何想法如何防止在最後一項後顯示分隔線?

歡呼和感謝

+1

請勿使用默認分隔線。您可以在回收站視圖xml項目中添加分隔線,並根據需要顯示或隱藏基礎。 – james

+0

發佈您的分頻器項目裝飾器代碼。 –

回答

12

試試這個代碼,它不會顯示最後一個項目的分隔符。

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> 

設置你的分頻器這樣的:

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

Upvoted,但不應該是** i <= childCount - 2 **或** i

+0

如果不想爲最後一個項目繪製分隔線,則必須設置其中的一個。 –

+0

是的,但你已經寫了**我

1

創建您自己的分頻器類(Example here

在繪製分隔的代碼,首先檢查如果你正在繪製分隔在列表的最後一個項目。如果是這樣,不要畫出來。

請注意,如果您覆蓋OnDrawOver它會在您的視圖的頂部繪製包括滾動條等。最好堅持OnDraw。谷歌上的很多例子,但是this是創建你自己的裝飾器的很好的教程。

+0

Yeap,onDrawOver在某些設備上提供了行爲不準確的結果。 –

1

下面是我在我的應用程序中使用的DividerDecorator類,它刪除了最後一項的底線。

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

您可以用下面的代碼將其設置爲你的RecyclerView

mRecyclerViewEvent.addItemDecoration(new DividerDecorator(context)); 

這裏的recyclerview_divider.xml

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

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

+0

我upvoted你,但覆蓋onDrawOver提供了不想要的結果。分頻器不斷地失常。 onDraw覆蓋證明對我更好。 –

9

提議here可以延長DividerItemDecoration這樣的:

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

不錯而且乾淨的想法,但是我更喜歡把onDraw覆蓋得更好,因爲這並不像我想要的那樣在外部類中表現得很好。 –

+0

此代碼不能編譯。 – David

+1

該解決方案比接受的解決方案更清潔,因爲它依賴於適配器位置而不是子索引。另外,爲了使它可重用,用公有子類替換匿名內部類,例如'公共類MiddleDividerItemDecoration擴展了DividerItemDecoration {...'。 –

0

您可以擴展RecyclerView.ItemDecoration並覆蓋onDrawgetItemOffsets

使用DividerItemDecoration作爲參考,並將裸露的基本要素複製到您自己的類中。

如果你這樣做,你會像這樣結束:

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

如果你比較這與DividerItemDecoration,你會發現,它消除了橫向佈局的支持。另外,您可以直接將drawable傳遞給構造函數。


- 1你看到這兩種方法是負責清除最後一個除法:

  1. 它可以防止onDraw從圖紙的最後一個分頻器。
  2. 它防止getItemOffsets提供空間(像素)爲最後一個分割器佔用。

實驗

  • getItemOffsets刪除- 1,但它留在onDraw
  • 打開 手機的開發人員選項中的「顯示佈局邊界」。
  • 設置你的分隔器高度的東西較大,如20dp

如果你現在運行你的項目,你會發現,雖然最後分頻器不繪製,空間仍然提供了它。

相關問題