2016-09-23 6 views
5

मैंने this answer से कोड को RecyclerView एस के लिए ठोस विभाजक लाइन बनाने के लिए उपयोग किया है।एंड्रॉइड - 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> 

लेकिन अगर मैं drawable संसाधन recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getContext())) करने के लिए अपने कॉल के माध्यम से पहुंचा जा सकता है कि के रूप में इस लागू करने की कोशिश, कोई रेखा पर तैयार की है:

मैं पहले से ही एक line_dashed.xml संसाधन है कि मैं अपने अनुप्रयोग में कहीं और का उपयोग कर रहा है सब।

एक हलचल रेखा को हल करने के लिए कैसे हल किया जाता है?

उत्तर

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

मैं इसे परीक्षण किया काम करना चाहिए।

अद्यतन:

android:layerType="software" 

recyclerView के लिए एक्सएमएल में इस पैरामीटर जोड़ने इसके अलावा अपने आकार drawable में आकार जोड़ें:

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

क्या आपने इसे @ प्रतिबंध-भू-इंजीनियरिंगरेटिंग जैसे डैटेड ड्रॉबल के साथ परीक्षण किया है? क्या यह वास्तव में काम करता है? –

+0

@Roman_Donchenko अद्यतन की जांच करें, इस परिवर्तन के साथ defenetly काम करता है। – Michael

+0

हाँ, अब यह काम करना चाहिए। –

0

एंड्रॉयड में धराशायी लाइन खींचें इतना आसान बात नहीं है। आपके जैसे ड्रोवेबल दिखाए गए हैं और यहां तक ​​कि केवल कैनवास (canvas.drawLine(..., paintWithDashEffect)) पर बिंदीदार रेखा खींचें) हमेशा काम नहीं करते (सभी उपकरणों के लिए नहीं)। आप android:layerType="software" या पथ खींच सकते हैं। आईएमएचओ, बेहतर समाधान डॉट लाइन को बिल्कुल आकर्षित नहीं करना है (केवल रेखा खींचें)। लेकिन अगर आपको वास्तव में बिंदीदार रेखा की आवश्यकता है, तो आप इस तरह @fearless उत्तर या 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); 
} 

} 
संबंधित मुद्दे