2016-09-23 2 views
5

Я использовал код от this answer, чтобы создать сплошную разделительную линию для моих RecyclerView.Android - Как добавить пунктирную разделительную линию для RecyclerView?

Однако, я хотел бы, чтобы линия была пунктирной/пунктирной.

У меня уже есть line_dashed.xml ресурс, который я использую в другом месте в моем приложении:

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
     android:shape="line" > 

    <stroke 
     android:color="@color/blue" 
     android:dashGap="12dp" 
     android:dashWidth="12dp" 
     android:width="1dp" /> 

</shape> 

Но если я стараюсь применять это как вытяжке ресурс, доступ к которому через мой призыв к recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getContext())), ни одна строка не втягивается в все.

Как решить так пунктирная линия показана?

ответ

5

Просто добавьте свой ресурс в этот элемент декоратора.

DividerItemDecoration decorator = new DividerItemDecoration(ContextCompat.getDrawable(getContext(), R.drawable.line_dashed)); 
recyclerView.addItemDecoration(decorator); 

и DividerItemDecorator класс:

public class DividerItemDecoration extends RecyclerView.ItemDecoration { 

    private Drawable mDivider; 
    private int mPaddingLeft; 

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

    public DividerItemDecoration(Drawable divider, int paddingLeft) { 
     mDivider = divider; 
     mPaddingLeft = paddingLeft; 
    } 

    @Override 
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
     super.getItemOffsets(outRect, view, parent, state); 
     if (mDivider == null) return; 
     if (parent.getChildAdapterPosition(view) < 1) return; 

     if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { 
      outRect.top = mDivider.getIntrinsicHeight(); 
     } else { 
      outRect.left = mDivider.getIntrinsicWidth(); 
     } 
    } 

    @Override 
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 
     if (mDivider == null) { 
      super.onDrawOver(c, parent, state); 
      return; 
     } 

     if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { 
      final int left = parent.getPaddingLeft() + mPaddingLeft; 
      final int right = parent.getWidth() - parent.getPaddingRight(); 
      final int childCount = parent.getChildCount(); 

      for (int i = 1; i < childCount; i++) { 
       final View child = parent.getChildAt(i); 
       final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); 
       final int size = mDivider.getIntrinsicHeight(); 
       final int top = child.getTop() - params.topMargin; 
       final int bottom = top + size; 
       mDivider.setBounds(left, top, right, bottom); 
       mDivider.draw(c); 
      } 

     } else { //horizontal 
      final int top = parent.getPaddingTop(); 
      final int bottom = parent.getHeight() - parent.getPaddingBottom(); 
      final int childCount = parent.getChildCount(); 

      for (int i = 1; i < childCount; i++) { 
       final View child = parent.getChildAt(i); 
       final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); 
       final int size = mDivider.getIntrinsicWidth(); 
       final int left = child.getLeft() - params.leftMargin; 
       final int right = left + size; 
       mDivider.setBounds(left, top, right, bottom); 
       mDivider.draw(c); 
      } 
     } 
    } 

    private int getOrientation(RecyclerView parent) { 
     if (parent.getLayoutManager() instanceof LinearLayoutManager) { 
      LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager(); 
      return layoutManager.getOrientation(); 
     } else 
      throw new IllegalStateException("DividerItemDecoration can only be used with a LinearLayoutManager."); 
    } 
} 

Должен работать я проверял.

UPDATE:

android:layerType="software" 

добавить этот параметр в XML для recyclerView Кроме того, добавить размеры в вашу форму вытяжке:

<size android:height="1dp"/> 
+0

Протестировано ли оно с помощью datted drawable, как показано на рисунке @ ban-geoengineering? Это действительно работает? –

+0

@Roman_Donchenko Проверить обновление, с этим изменяет defenetly работает. – Michael

+0

Да, теперь он должен работать. –

0

Draw пунктирная линия в Android не так просто сделка. Дрожащий, как вы показали, и даже просто рисуете пунктирную линию на canwas (canvas.drawLine(..., paintWithDashEffect)) не всегда работает (не для всех устройств). Вы можете использовать android:layerType="software" или рисовать дорожку. ИМХО, лучшим решением является вовсе не рисовать пунктирную линию (рисовать только линию). Но если вам действительно нужна пунктирная линия, вы можете использовать ответ @fearless или что-то вроде этого:

public class DividerItemDecoration extends RecyclerView.ItemDecoration { 

private Paint mPaint; 
private int mDividerSize; 

public DividerItemDecoration(int dividerSize) { 
    mDividerSize = dividerSize; 
    mPaint = new Paint(); 
    mPaint.setColor(ContextCompat.getColor(context, R.color.colorAccent)); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeWidth(dividerSize); 
    mPaint.setPathEffect(new DashPathEffect(new float[]{dashGap,dashWidth},0)); 
} 

@Override 
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
    outRect.bottom = mDividerSize; 
} 

@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(); 
    Path path = new Path(); 
    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 + mDividerSize/2; 

     path.moveTo(left, top); 
     path.lineTo(right, top); 
    } 
    c.drawPath(path, mPaint); 
} 

} 
Смежные вопросы