2016-09-23 27 views
5

this answerのコードを使用してRecyclerViewのソリッドセパレータラインを作成しました。Android - RecyclerViewに点線または点線の区切り線を追加するにはどうすればよいですか?

しかし、私は線を点線で点けたいと思います。

<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()))に私のコールを介してアクセスされる描画可能リソースとして、これを適用しようとすると、何行がで描画されていない:

は、私はすでに、私は私のアプリの他の場所で使用していますline_dashed.xmlリソースを持っていますすべて。

どのように破線を表示するのですか?

答えて

5

drawableリソースをこのアイテムデコレータに追加するだけです。

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" 

また、あなたの形状の描画可能にサイズを追加recyclerView ためのXMLにこのパラメータを追加します。

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

@ ban-geoengineeringのような細かいドロブルでテストしましたか?本当に効果がありますか? –

+0

@Roman_Donchenkoこの変更は致命的なものであり、アップデートを確認してください。 – Michael

+0

うん、今それは動作するはずです。 –

0

は、Androidの破線を描画しますので、簡単に取引ではありません。あなたが示したようなDrowableとcanwas(canvas.drawLine(..., paintWithDashEffect))の点線を描くだけでは、必ずしもすべてのデバイスで動作するわけではありません。 android:layerType="software"を使用するか、パスを描きます。 IMHO、よりよい解決策は点線を描かないことです(ちょうど線を引く)。しかし、実際に点線が必要な場合は、次のように@fearless answerまたはsomethinkを使用することができます:

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

} 
関連する問題