Android进阶 RecyclerView自定义分割线的使用

RecyclerView控件的特点:

        从整体上看,RecyclerView架构提供了一种插拔式的体验,它具有高度的解耦、异常的灵活性和更高的效率,通过设置它提供的不同LayoutManager、ItemDecoration、ItemAnimator可实现更加丰富的效果,但是RecyclerView也有缺点:设置列表的分割线时需要自定义,另外列表的点击事件需要自己实现。

添加依赖:

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'

使用RecyclerView:

    private RecyclerView recyclerView;
    private List mList;
    private HomeAdapter homeAdapter;
    private LinearLayoutManager manager;
      manager=new LinearLayoutManager(this);
      //manager.setOrientation(LinearLayoutManager.HORIZONTAL);
      recyclerView.setLayoutManager(manager);//设置布局管理器用于设置条目的排列方式(默认垂值)
      //添加分割线
      recyclerView.addItemDecoration(new 
      DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL_LIST));
      recyclerView.setItemAnimator(new DefaultItemAnimator());//设置item增加和删除时的动画
      homeAdapter=new HomeAdapter(this,mList);//传出数据
      recyclerView.setAdapter(homeAdapter);//添加adapter

View布局:

主布局activity_main.xml文件:




    
    

子布局item_recycler.xml文件:




    

Adapter适配器和分割线:

       Adapter最大的改进就是对ViewHolder进行了封装定义,我们只需要自定义一个ViewHolder继承RecyclerView.ViewHolder就可以了,另外,Adapter继承了RecyclerView.Adapter,在onCreateViewHolder中加载条目布局,在onBindViewHolder中将视图与数据进行绑定。

1、类似于ListView式布局所对应的适配器HomeAdapter.java文件:

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.dpl.recyclerviewdemo.R;
import java.util.List;

/**
 * 功能:数据适配器
 */
public class HomeAdapter extends RecyclerView.Adapter {

    private Context context;
    private List mList;
    private OnItemClickListener onItemClickListener;

    public HomeAdapter(Context context, List mList){//传入数据
        this.context=context;
        this.mList=mList;
    }
    public void removeData(int position){    //移除数据
        mList.remove(position);
        notifyItemRemoved(position);
    }
    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_recycler,viewGroup,false));
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int i) {
        myViewHolder.textView.setText(mList.get(i));
        if (onItemClickListener!=null){
            myViewHolder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos=myViewHolder.getLayoutPosition();
                    onItemClickListener.onItemClick(myViewHolder.textView,pos);
                }
            });
            myViewHolder.textView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int pos=myViewHolder.getLayoutPosition();
                    onItemClickListener.onItemLongClick(myViewHolder.textView,pos);
                    return false;
                }
            });
        }
    }
    @Override
    public int getItemCount() {
        return mList.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        MyViewHolder(@NonNull View itemView) {
            super(itemView);
            textView=itemView.findViewById(R.id.tv_item);
        }
    }

    /**
     * 自定义列表条目的点击事件
     */
    public interface OnItemClickListener{
        void onItemClick(View view,int position);
        void onItemLongClick(View view,int position);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener=onItemClickListener;
    }

}

设置类似于ListView的自定义分割线DividerItemDecoration.java文件:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * 功能:绘制类似ListView 的RecyclerView子布局item的分割线
 */

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS=new int[]{android.R.attr.listDivider};//android.R.attr.listDivider作为Item间的系统默认分割线,并且支持横向和纵向
    public static final int HORIZONTAL_LIST= LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST=LinearLayoutManager.VERTICAL;
    private Drawable mDivider;//Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),象
    private int mOrientation;
    public DividerItemDecoration(Context context,int orientation){
        final TypedArray a=context.obtainStyledAttributes(ATTRS);
        //用TypedArray获取XML中的属性,通过Context的obtainStyledAttributes方法创建TypedArray,然后用getXXX来获取对应的属性。
        mDivider=a.getDrawable(0);
        a.recycle();//不要忘记回收
        setOrientation(orientation);
    }
    public void setOrientation(int orientation){//设置排列方向
        if (orientation!=HORIZONTAL_LIST&&orientation!=VERTICAL_LIST){
            throw new IllegalArgumentException("invalid orientation");//非法数据异常处理
        }
        mOrientation=orientation;
    }

    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent) {//根据传进来的orientation进行绘制
        if (mOrientation==VERTICAL_LIST){
            drawVertical(c,parent);
        }else {
            drawHorizontal(c,parent);
        }
    }
    public void drawVertical(Canvas c,RecyclerView parent){//绘制纵向分割线
        final int left=parent.getPaddingLeft();//获取左边界距离
        final int right=parent.getWidth()-parent.getPaddingRight();
        final int childCount=parent.getChildCount();//获取子布局数量
        for (int i=0;i

运行图:

Android进阶 RecyclerView自定义分割线的使用_第1张图片

 2、实现GridView

适配器使用HomeAdapter.java文件。

自定义Item分割线DividerGridItemDecoration.java文件:


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;

/**
 * 功能:GridViewItem分割线
 */
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS=new int[]{android.R.attr.listDivider};
    private Drawable mDivider;
    public DividerGridItemDecoration(Context context){
        final TypedArray array=context.obtainStyledAttributes(ATTRS);
        mDivider=array.getDrawable(0);
        array.recycle();//回收
    }

    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        drawHorizontal(c,parent);
        drawVertical(c,parent);
    }
    private int getSpanCount(RecyclerView parent){
        //获取列数
        int spanCount=-1;
        RecyclerView.LayoutManager layoutManager=parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager){
            spanCount=((GridLayoutManager)layoutManager).getSpanCount();
        }else if (layoutManager instanceof StaggeredGridLayoutManager){
            spanCount=((StaggeredGridLayoutManager)layoutManager).getSpanCount();
        }
        return spanCount;
    }
    public void drawHorizontal(Canvas c,RecyclerView parent){
        int childCount=parent.getChildCount();
        for (int i=0;i=childCount)//如果是最后一列,则不需要绘制右边
                    return true;
            }
        }
        return false;
    }
    private boolean isLastRaw(RecyclerView parent,int position,int spanCount,int childCount){
        RecyclerView.LayoutManager layoutManager=parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager){
            childCount=childCount-childCount%spanCount;
            if (position>=childCount)//如果是最后一行,则不需要绘制底部
                return true;
        }else if (layoutManager instanceof  StaggeredGridLayoutManager){
            int orientation=((StaggeredGridLayoutManager)layoutManager).getOrientation();
            //StaggeredGridLayoutManager且纵向滚动
            if (orientation==StaggeredGridLayoutManager.VERTICAL){
                childCount=childCount-childCount%spanCount;
                //如果是最后一行,则不需要绘制底部
                if (position>=childCount)
                    return true;
            }else{//StaggeredGridLayoutManager且横向滚动
                //如果是最后一行,则不需要绘制底部
                if ((position+1)%spanCount==0){
                    return true;
                }
            }
        }
        return false;
    }
    public void getItemOffsets(Rect outRect,int itemPosition,RecyclerView parent){
        int spanCount=getSpanCount(parent);//获取列数
        int childCount=parent.getAdapter().getItemCount();
        if (isLastRaw(parent,itemPosition,spanCount,childCount)){//如果是最后一行,则不需要绘制底部
            outRect.set(0,0,mDivider.getIntrinsicWidth(),0);
        }else if (isLastColum(parent,itemPosition,spanCount,childCount)){
            outRect.set(0,0,0,mDivider.getIntrinsicHeight());
        }else {
            outRect.set(0,0,mDivider.getIntrinsicWidth(),mDivider.getIntrinsicHeight());
        }
    }
}

运行图:

Android进阶 RecyclerView自定义分割线的使用_第2张图片

3、实现瀑布流StaggeredGridView.java文件:

Adapter适配器:StaggeredHomeAdapter.java文件

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.dpl.recyclerviewdemo.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 功能:瀑布流的适配器
 */
public class StaggeredHomeAdapter extends RecyclerView.Adapter {
    private List mDatas;
    private LayoutInflater mInflater;
    private List mHeights;
    private OnItemClickListener onItemClickListener;

    public interface OnItemClickListener{
        void onItemClick(View view,int position);
        void onItemLongClick(View view,int position);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener=onItemClickListener;
    }

    public StaggeredHomeAdapter(Context context,List datas){
        mInflater=LayoutInflater.from(context);
        mDatas=datas;
        mHeights=new ArrayList();
        for (int i=0;i

 

瀑布流的分割线使用DividerGridItemDecoration.java文件。

运行图:

Android进阶 RecyclerView自定义分割线的使用_第3张图片

 

Control控制器:MainActivity.java文件

import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.widget.Toast;

import com.dpl.recyclerviewdemo.adapter.HomeAdapter;
import com.dpl.recyclerviewdemo.adapter.StaggeredHomeAdapter;
import com.dpl.recyclerviewdemo.util.DividerGridItemDecoration;
import com.dpl.recyclerviewdemo.util.DividerItemDecoration;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private List mList;
    private HomeAdapter homeAdapter;
    private LinearLayoutManager manager;
    private StaggeredHomeAdapter staggeredHomeAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();

    }
    private void initData(){//初始化数据
        mList=new ArrayList<>();
        for (int i=1;i<100;i++){
            mList.add(i+"");
        }
    }
    private void initView(){   //初始化view
        recyclerView=this.findViewById(R.id.id_recyclerView);
        //设置ListView
//        setListView();
        //设置GridView
//        setGridView();
        //设置瀑布流StaggeredGridView
        setWaterfallView();
    }
    public void setListView(){
        manager=new LinearLayoutManager(this);
        //manager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(manager);
        recyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL_LIST));
        recyclerView.setItemAnimator(new DefaultItemAnimator());//设置item增加和删除时的动画
        homeAdapter=new HomeAdapter(this,mList);//传出数据
        setLister();
        recyclerView.setAdapter(homeAdapter);//添加adapter
    }
    public void setGridView(){
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
        recyclerView.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
        recyclerView.setItemAnimator(new DefaultItemAnimator());//设置item增加和删除时的动画
        homeAdapter=new HomeAdapter(this,mList);//传出数据
        setLister();
        recyclerView.setAdapter(homeAdapter);//添加adapter
    }

    public void setWaterfallView(){
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
        recyclerView.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        staggeredHomeAdapter=new StaggeredHomeAdapter(this,mList);
        staggeredHomeAdapter.setOnItemClickListener(new StaggeredHomeAdapter.OnItemClickListener(){
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(MainActivity.this,"点击第"+(position+1)+"条",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onItemLongClick(View view, final int position) {
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("确认删除吗?")
                        .setNegativeButton("取消",null)
                        .setPositiveButton("确认", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                staggeredHomeAdapter.removeData(position);
                            }
                        });
            }
        });
        recyclerView.setAdapter(staggeredHomeAdapter);
    }
    public void setLister(){
        homeAdapter.setOnItemClickListener(new HomeAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(MainActivity.this,"点击第"+(position+1)+"条",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onItemLongClick(View view, final int position) {
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("确认删除吗?")
                        .setNegativeButton("取消",null)
                        .setPositiveButton("确认", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                homeAdapter.removeData(position);
                            }
                        });
            }
        });
    }
}

参考博客:

https://blog.csdn.net/crazyZhangxl/article/details/81043205

https://blog.csdn.net/dodod2012/article/details/79030559

https://blog.csdn.net/SuperBigLw/article/details/53404489

你可能感兴趣的:(Android,Native,进阶)