RecyclerView添加分割线

34 篇文章 1 订阅
4 篇文章 0 订阅

                                RecyclerView添加分割线

RecyclerView没有默认的分割线 需要自己去绘制,实现rv的分割线需要继承ITEMDecoration,先看两张效果图

 

两种实现的方法,一种是实现了 水平或垂直的分割线,一种是实现了网格的分割线。

我把实现两种方式的代码放在下面了 根据实际需要进行使用。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="item">
    </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

recycler_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="item"/>
</LinearLayout>

drawable下的item_divder.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="item"/>
</LinearLayout>

RecyclerViewAdapter

public class RecylerViewAdapter extends RecyclerView.Adapter<RecylerViewAdapter.MyAdapterHolder> {
    private List<String> stringList;
    private onClickListener onItemListener;
    private List<Integer> heights;
    public RecylerViewAdapter(List stringList){
        this.stringList=stringList;
        heights = new ArrayList<>();
        for (int i = 0; i < stringList.size(); i++) {
            heights.add((int)(200+Math.random()*50));
        }
    }
    class MyAdapterHolder extends RecyclerView.ViewHolder{
        public TextView textView;
        public MyAdapterHolder(@NonNull View itemView) {
            super(itemView);
            textView=itemView.findViewById(R.id.tv_text);

        }
    }
    @NonNull
    @Override
    public MyAdapterHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        MyAdapterHolder holder=new MyAdapterHolder(View.inflate(viewGroup.getContext(),R.layout.recycler_item,null));
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull final MyAdapterHolder viewHolder, int i) {
        //绑定数据
        final ViewGroup.LayoutParams params = viewHolder.textView.getLayoutParams();
        params.height = heights.get(i);
        viewHolder.textView.setBackgroundColor(Color.rgb(100, (int)(Math.random()*255), (int)(Math.random()*255)));
        viewHolder.textView.setLayoutParams(params);
        viewHolder.textView.setText(stringList.get(i));
        if(onItemListener!=null){
            viewHolder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemListener.itemclick(v,viewHolder.getLayoutPosition());
                }
            });
        }
    }


    @Override
    public int getItemCount() {
        return stringList.size();
    }
    public interface onClickListener{
        void itemclick(View view,int position);
    }
    public void setOnItemClick(onClickListener listener){
        onItemListener =listener;
    }
}

绘制水平和垂直的ItemDecoration

public class RecyclerItemDecoration extends RecyclerView.ItemDecoration {
    private int mOrientation=LinearLayoutManager.VERTICAL;
    private Drawable mDivider;
    private int[] attrs=new int[]{
            android.R.attr.listDivider
    };
    public RecyclerItemDecoration(Context context,int orientation){
        TypedArray typedArray=context.obtainStyledAttributes(attrs);
        mDivider=typedArray.getDrawable(0);
        typedArray.recycle();
        setOrientation(orientation);
    }
    public void setOrientation(int orientation){
        if (orientation!= LinearLayoutManager.HORIZONTAL    && orientation!=LinearLayoutManager.VERTICAL){
            throw new IllegalArgumentException("来了老弟");
        }
        this.mOrientation=orientation;


    }
    /**
     * recyclerView 会回调该方法 需要自己去绘制间隔线
     * @param c
     * @param parent
     * @param state
     */
    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        if (mOrientation==LinearLayoutManager.VERTICAL){
            draVertical(c,parent);
        }else {
            draHorizontal(c,parent);
        }
        super.onDraw(c, parent, state);
    }

    /**
     * 垂直分割线
     * @param c
     * @param parent
     */
    private void draHorizontal(Canvas c, RecyclerView parent) {
        int top = parent.getPaddingTop();
        int bottom = parent.getHeight() - parent.getPaddingBottom();
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount ; i++) {
            View child = parent.getChildAt(i);

            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int left = child.getRight() + params.rightMargin + Math.round(ViewCompat.getTranslationX(child));
            int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top , right, bottom);
            mDivider.draw(c);
        }
    }

    /**
     * 水平分割线
     * @param c
     * @param parent
     */
    private void draVertical(Canvas c, RecyclerView parent) {
        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.getTop()+params.topMargin+ Math.round(ViewCompat.getTranslationY(child));
            int bottom=top+mDivider.getIntrinsicHeight();
            mDivider.setBounds(left,top,right,bottom);
            mDivider.draw(c);
        }
    }

    /**
     *1、调用此方法获取条目偏移量(首先会先获取条目之间的间隙宽度---》通过rect来提现 矩形区域)
     * 2、获取条目的偏移量 (所有条目都会调用该方法)
     * @param outRect 矩形区域 left、top、bottom、right
     * @param view
     * @param parent
     * @param state
     */
    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            //        super.getItemOffsets(outRect, view, parent, state);
        if (mOrientation==LinearLayoutManager.VERTICAL){
            outRect.set(0,0,0,mDivider.getIntrinsicHeight());
        }else {
            outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
        }
    }
}

绘制网格布局的ItemDecoration


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

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

    /**
     * 绘制水平间隔线
     * @param c
     * @param parent
     */
    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 = (RecyclerView.LayoutParams) child.getLayoutParams();
            int left=child.getLeft()-params.leftMargin;
            int right=child.getRight()+ params.rightMargin;
            int top=child.getBottom()+params.bottomMargin;
            int bottom=top+mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    /**
     * 绘制垂直间隔线
     * @param c
     * @param 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 = (RecyclerView.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);
        }
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, int itemPosition, @NonNull RecyclerView parent) {
        //        super.getItemOffsets(outRect, itemPosition, parent);
        int right = mDivider.getIntrinsicWidth();
        int bottom = mDivider.getIntrinsicHeight();
        //代表四个方向的偏移值

        if (isLastColumn(itemPosition,parent)){
            Log.d("DividerGirdViewItemDeco", "右");
            right=0;
        } else if (isLastRow(itemPosition,parent)){
            Log.d("DividerGirdViewItemDeco", "下");
            bottom=0;
        }
        outRect.set(0,0,right,bottom);


    }

    /**
     * 是否最后一行
     * @param itemPosition
     * @return
     */
    private boolean isLastRow(int itemPosition,RecyclerView parent) {
        int spanCount =  getSpanCount(parent);
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        //有多少列
        if(layoutManager instanceof GridLayoutManager){
            int childCount = parent.getAdapter().getItemCount();
            int lastRowCount = childCount%spanCount;
            //最后一行的数量小于spanCount
            if(lastRowCount==0||lastRowCount<spanCount){
                return true;
            }
        }
        return false;
    }

    /**
     * 是否是最后一列
     * @param itemPosition
     * @return
     */
    private boolean isLastColumn(int itemPosition,RecyclerView parent) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        //有多少列
        if(layoutManager instanceof GridLayoutManager){
            int spanCount = getSpanCount(parent);
            if((itemPosition+1)%spanCount==0){
                return true;
            }
        }
        return false;
    }
    private int getSpanCount(RecyclerView parent){
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if(layoutManager instanceof GridLayoutManager){
            GridLayoutManager lm = (GridLayoutManager)layoutManager;
            int spanCount = lm.getSpanCount();
            return spanCount;
        }
        return 0;
    }
}

主页面调用MainActivity


public class MainActivity extends AppCompatActivity {
    private RecyclerView rvView;
    private List stringLists;
    private RecylerViewAdapter adapterHolder;
    private DividerGirdViewItemDecoration itemDecoration;
    private RecyclerItemDecoration decoration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rvView = (RecyclerView) findViewById(R.id.rv_view);
        stringLists=new ArrayList();
        for (int i=0;i<100;i++){
            stringLists.add("条目"+i);
        }
    /*    //垂直或者水平效果
        decoration=new RecyclerItemDecoration(this, LinearLayoutManager.VERTICAL);
        rvView.setLayoutManager(new LinearLayoutManager(this));
        rvView.addItemDecoration(decoration);*/
        //瀑布流效果
        itemDecoration=new DividerGirdViewItemDecoration(this);
        rvView.setLayoutManager(new StaggeredGridLayoutManager(3,LinearLayoutManager.VERTICAL));
        rvView.addItemDecoration(itemDecoration);
        adapterHolder = new RecylerViewAdapter(stringLists);

        adapterHolder.setOnItemClick(new RecylerViewAdapter.onClickListener() {
            @Override
            public void itemclick(View view, int position) {
                Toast.makeText(MainActivity.this, "position:" + position, Toast.LENGTH_SHORT).show();
            }
        });
        rvView.setAdapter(adapterHolder);

    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值