RecyclerView的使用详解

RecyclerView的使用详解

RecyclerView的Adapter:
1.item的重用无需关心;
2.强制要求实现一个ViewHolder;
创建一个类(MyAdapter)继承于RecyclerView.Adapter;
定义一个ViewHolder;

搭建基础Adapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>
{
    private Context mContext;
    private List<String> dataList = new ArrayList<>();

    public MyAdapter(Context context, List<String> data)
    {
        mContext = context;
        dataList = data;
    }

   /**
     * 当解析布局这样子写时:
     * View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, parent, false);
     * item中最外层布局的layout属性才起作用;eg:
     * 
     * 当解析布局这样子写时:
     * View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, null);
     * item中最外层布局的layout属性则不起作用;
     * 

* viewType:多布局使用的; * * @param parent * @param viewType * @return */ @NonNull @Override public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main, parent, false); return new MyHolder(view); } @Override public void onBindViewHolder(@NonNull MyHolder holder, int position) { holder.textView.setText(dataList.get(position)); } @Override public int getItemCount() { return dataList.size(); } public class MyHolder extends RecyclerView.ViewHolder { private TextView textView; /** * 接收Item的布局对象 * * @param itemView */ public MyHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.textView); } } }

使用RecyclerView:

private MyAdapter myAdapter;
private RecyclerView listRecyclerView;
private List<String> listData = new ArrayList<>();

listRecyclerView = findViewById(R.id.recycler_view);
//设置布局管理器;
listRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//new LinearLayoutManager;跟ListView一样的排列方式;
//LinearLayoutManager.HORIZONTAL:设置滑动的方向为横向;
//LinearLayoutManager.VERTICAL:设置滑动的方向为纵向;
//reverseLayout-->false:设置数据正序排列还是反序排列;eg:1...26为正序设置为false;26..1为反序设置为true;
listRecyclerView.setLayoutManager(
        new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
//new GridLayoutManager:跟GridView一样的排列方式;
//3-->spanCount:如果方向为LinearLayoutManager.VERTICAL:则是设置有多少列;
// LinearLayoutManager.HORIZONTAL:则是设置有多少行;
//LinearLayoutManager.HORIZONTAL:设置方向;
//reverseLayout-->false:设置数据正序排列还是反序排列;eg:1...26为正序设置为false;26..1为反序设置为true;
listRecyclerView.setLayoutManager(
        new GridLayoutManager(this, 3, LinearLayoutManager.HORIZONTAL, false));
//new StaggeredGridLayoutManager:瀑布流的排列方式;即当每个item需要显示的数据大小不一样时,则每个item的高度不会对齐;
//3-->spanCount:如果方向为LinearLayoutManager.VERTICAL:则是设置有多少列;
// LinearLayoutManager.HORIZONTAL:则是设置有多少行;
//LinearLayoutManager.HORIZONTAL:设置方向;
listRecyclerView.setLayoutManager(
        new StaggeredGridLayoutManager(3, LinearLayout.HORIZONTAL));
myAdapter = new MyAdapter(this, listData);
listRecyclerView.setAdapter(myAdapter;

ps–>item布局的最外层布局必须使用wrap_content;如果使用match_parent则会一个Item占一页;

getAdapterPosition():获得适配器的下标;当前点击的Item的下标;
ps:瀑布流的排列形式;
RecyclerView的使用详解_第1张图片

ReyclerView的Item的点击事件:

1.在Adapter中创建:
第一种创建方式:

public class MyHolder extends RecyclerView.ViewHolder
{
    private TextView textView;

    /**
     * 接收Item的布局对象
     *
     * @param itemView
     */
    public MyHolder(@NonNull View itemView)
    {
        super(itemView);
        textView = itemView.findViewById(R.id.textView);
        itemView.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (onItemClickListener != null)
                {
                    onItemClickListener.onItemClick(v, getAdapterPosition());
                }
            }
        });
    }
}

private OnItemClickListener onItemClickListener;

public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
    this.onItemClickListener = onItemClickListener;
}

public interface OnItemClickListener
{
    void onItemClick(View view, int position);
}

2.第二种创建方式:

@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position)
{
    holder.textView.setText(dataList.get(position));
    holder.itemView.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            if (onItemClickListener != null)
            {
                onItemClickListener.onItemClick(v, position);
            }
        }
    });
}
private OnItemClickListener onItemClickListener;

public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
    this.onItemClickListener = onItemClickListener;
}

public interface OnItemClickListener
{
    void onItemClick(View view, int position);
}

在MainActivity中使用:

myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener()
{
    @Override
    public void onItemClick(View view, int position)
    {
        //添加数据单条数据时;
        //position-->添加在position的位置;
        //使用notifyItemInserted;则只会刷新添加的那条数据;
        myAdapter.notifyItemInserted(position);
        //添加多条数据;
        //position-->从position的位置开始添加;
        //itemCount:5-->一共需要添加几条;
        myAdapter.notifyItemRangeInserted(position, 5);
        //删除单条数据;
        //position-->删除在position的位置的数据;
        myAdapter.notifyItemRemoved(position);
        //删除多条数据;
        //position-->从position的位置开始删除;
        //itemCount:5-->一共需要删除几条;
        myAdapter.notifyItemRangeRemoved(position, 5);
        //点击当前的position,使数据移到最顶端;
        String str = listData.remove(position);
        listData.add(str);
        myAdapter.notifyItemMoved(position, 0);
        //修改数据;
        myAdapter.notifyItemChanged(position);
        //批量修改
        myAdapter.notifyItemRangeChanged(position, 6);
        //滚动到第几个下标;
        listRecyclerView.scrollToPosition(position);
    }
});

设置显示的动画:

listRecyclerView.setItemAnimator(new DefaultItemAnimator());

设置每个item的分割线:

listRecyclerView.addItemDecoration(new MyItemDecoration(this));

自定义一个分割线的类:

public class MyItemDecoration extends RecyclerView.ItemDecoration
{
    /**
     * 系统的Drawable,用来话ListView的分割线的资源
     */
    private int[] ATTR = {android.R.attr.listDivider};
    /**
     * 分割线的资源;
     */
    private Drawable drawable;

    public MyItemDecoration(Context context)
    {
        //获得Drawable资源的属性;
        TypedArray typedArray = context.obtainStyledAttributes(ATTR);
        //获取第一个Drawable;
        drawable = typedArray.getDrawable(0);
        //释放资源;
        typedArray.recycle();
    }

    /**
     * 分割线的绘制;
     *
     * @param c
     * @param parent
     * @param state
     */
    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent,
                       @NonNull RecyclerView.State state)
    {
        super.onDraw(c, parent, state);
        //parent.getChildCount()-->获取一共有多少个Item;
        for (int i = 0; i < parent.getChildCount(); i++)
        {
            //最后一个不用绘制分割线;
            if (i == parent.getChildCount() - 1)
            {
                return;
            }
            //获取第i个ItemView;
            View itemView = parent.getChildAt(i);
            //获取item的左边的坐标;
            int left = itemView.getLeft();
            //获取item的下边的坐标;
            int top = itemView.getBottom();
            //获取item的右边的坐标;
            int right = itemView.getRight();
            //获取分割线的下边的坐标;drawable.getIntrinsicHeight()-->分割线资源的高度;
            int bottom = itemView.getBottom() + drawable.getIntrinsicHeight();
            //设置分割线的坐标;
            drawable.setBounds(left, top, right, bottom);
            //绘制画布;
            drawable.draw(c);
        }
    }

    /**
     * 设置每个Item需要预留出来的空间,供分割线使用;
     *
     * @param outRect
     * @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);
        // drawable.getIntrinsicHeight():底部需要预留出来的空间;
        outRect.set(0, 0, 0, drawable.getIntrinsicHeight());
    }
}

你可能感兴趣的:(Android,android)