美文网首页
RecyclerView系列(三)分割线终极封装

RecyclerView系列(三)分割线终极封装

作者: Ayres | 来源:发表于2017-07-19 16:44 被阅读0次

    上面写了一篇自定义分割线,重在理解分割线的绘制原理,这篇侧重于项目实战中应用。

    1.创建继承ItemDecoration

    构造创建,这次使用attrs 的方式

     private Drawable mDivider;
      private int[] attrs = new int[]{
            android.R.attr.listDivider
       };
    public DividerGridItemDecoration(Context context) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs);
        mDivider = typedArray.getDrawable(0);
        typedArray.recycle();
    }
    

    在清单文件中配置主题

       <activity android:name=".fenline.RecyclerViewActivity"
            android:theme="@style/AppTheme"/>
    

    在主题中配置listDivider属性

     <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:listDivider">@drawable/list_item_divider</item>
    </style>
    

    然而list_item_divider自己绘制的分割线样式,举个例子:

     <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size android:height="0.5dp"
        android:width="0.5dp"
        />
     <solid android:color="@color/login_color" />
    </shape>
    

    2.onDraw方法区分逻辑

    onDraw方法区分是水平还是竖直分割线

       @Override
       public void onDraw(Canvas c, RecyclerView parent, State state) {
        drawVertical(c, parent);
        drawHorizontal(c, parent);
       }
    

    绘制竖直分割线方法

    private void drawVertical(Canvas c, RecyclerView parent) {
        //绘制垂直间隔线(垂直的矩形)
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (LayoutParams) child.getLayoutParams();
            int left = child.getRight() + params.rightMargin;
            int right = left + mDivider.getIntrinsicWidth();
            int top = child.getTop() - params.topMargin;
            int bottom = child.getBottom() + params.bottomMargin;
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
    

    绘制水平分割线方法

      private void drawHorizontal(Canvas c, RecyclerView parent) {
        // 绘制水平间隔线
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (LayoutParams) child.getLayoutParams();
            int left = child.getLeft() - params.leftMargin;
            int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth();
            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
    

    3.getItemOffsets逻辑实现

      @Override
       public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
        // 四个方向的偏移值
        int right = mDivider.getIntrinsicWidth();
        int bottom = mDivider.getIntrinsicHeight();
    
        int position = ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
    
        if (isLastColumn(position, parent)) {// 是否是最后一列
            right = 0;
        }
        if (isLastRow(position, parent)) {// 是否是最后一行
            bottom = 0;
        }
        outRect.set(0, 0, right, bottom);
    }
    

    其他方法

     /**
     * 是否是最后一列
     */
    public boolean isLastColumn(int itemPosition, RecyclerView parent) {
        int spanCount = getSpanCount(parent);
        if ((itemPosition + 1) % spanCount == 0) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * 是否是最后一行
     */
    public boolean isLastRow(int itemPosition, RecyclerView parent) {
    
        int spanCount = getSpanCount(parent);
    
        int childCount = parent.getAdapter().getItemCount();
    
        int rowNumber = childCount % spanCount == 0 ? childCount / spanCount : (childCount / spanCount) + 1;
    
        if (itemPosition > ((rowNumber - 1) * spanCount - 1)) {
            return true;
        }
    
        return false;
    }
    
    /**
     * 获取一行有多少列
     */
    public int getSpanCount(RecyclerView parent) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
    
        if (layoutManager instanceof GridLayoutManager) {
            // 获取一行的spanCount
            GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            int spanCount = gridLayoutManager.getSpanCount();
            return spanCount;
        }
        return 1;
    }
    

    4.使用

    使用方法很简单,只需添加如下这句:

       mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
    

    相关文章

      网友评论

          本文标题:RecyclerView系列(三)分割线终极封装

          本文链接:https://www.haomeiwen.com/subject/qiwlkxtx.html