欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RecycleView使用总结二

程序员文章站 2022-05-15 19:22:02
...

一. 摘要

    RecycleView没有像ListView那样直接提供添加headerView和footerView的方法,所以要实现这样的效果需要自己去实现。本文记录了通过item类型作为区分,来为列表添加headerView的整个流程。同时,记录了针对线性布局,网格布局,瀑布流布局的适配方法。

   左右滑删除,拖动Item是很常见的功能。针对这些功能,安卓API中提供了相关的辅助类ItemTouchHelper等,借助于这些类,能够很方便的实现这些功能。本文也将针对ItemTouchHelper的具体使用方式。

二. 为RecycleView添加headerView

    整体思路:通过item类型进行区分,把RecycleView的第一个Item作为头布局。整体实现思路非常简单,主要代码如下,详细代码会在文章最后给出。要注意的是对有没有添加headerView的判断,以及对应情况下,对Item位置的处理,如果添加了头布局,那么我们从数据集中拿Item的数据时就不能直接利用参数position来取,因为他们对应的位置已经变了。为此需要获取真实位置,即下面的getRealPosition()方法进行的处理。

    private List<ItemInfo>itemLists;
    private View headView;
    private final int HEAD_VIEW_TYPE=1;
    private final int NORMAL_ITEM_TYPE=2;

    public RecycleAdapter(List<ItemInfo> itemLists) {
        this.itemLists = itemLists;
    }

    class ViewHolder extends RecyclerView.ViewHolder{
        ImageView image;
        TextView textView;

        public ViewHolder(View view){
            super(view);
            if (view!=headView) {
                image = view.findViewById(R.id.image);
                textView = view.findViewById(R.id.text);
            }
        }
    }
    @Override
    public RecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType==HEAD_VIEW_TYPE)
            return new ViewHolder(headView);
       View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item,parent,false);
       ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecycleAdapter.ViewHolder holder, int position) {
        if (getItemViewType(position) == HEAD_VIEW_TYPE)
            return;
        try {
            ItemInfo info = itemLists.get(getRealPosition(position));
            holder.textView.setText(info.getTitle());
            holder.image.setImageResource(info.getImgid());
        }catch (Exception e){
            Log.i("jm", "jm--onBindViewHolder: "+position);
        }

    }

    private int getRealPosition(int position){
        if (headView!=null){
            return position-1;
        }

        return position;
    }

    @Override
    public int getItemCount() {
        return headView==null?itemLists.size():itemLists.size()+1;
    }

    @Override
    public int getItemViewType(int position) {
        if (headView!=null&&(position==0)){
            return HEAD_VIEW_TYPE;
        }
        return NORMAL_ITEM_TYPE;
    }


    public void setHeaderView(View view){
        headView=view;
        notifyDataSetChanged();
    }

    public View getHeaderView(){
       return headView;
    }

    通过以上处理,在需要添加headerView的地方直接调用setHeaderView()方法即可。在使用时发现,由于该方法的实质是把一个item当作头布局,所以,当使用线性布局时效果还行,但当我们采用网格布局或者瀑布流布局,这种一行要显示多个item时,添加的headerView将会直接作为一个item显示在第一个位置,效果如下,这显然不是我们想要的。

RecycleView使用总结二             RecycleView使用总结二

  对此,我们需要针对GridLayoutManager和StaggeredGridLayoutManager做相应的处理,以下是针对两种所做的处理,方法引自网络,文章最后会给出链接。

针对GridLayoutManager,在适配器中添加如下代码,该方法的目的是在绑定RecycleView时,先判断出布局样式,再利用setSpanSizeLookup方法设置头布局跨多行显示,达到第一行只显示头布局的效果:

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return getItemViewType(position) == HEAD_VIEW_TYPE
                            ? gridManager.getSpanCount() : 1;
                }
            });
        }
    }

针对StaggeredGridLayoutManager,做如下处理:

    @Override
    public void onViewAttachedToWindow(ViewHolder holder) {
        super.onViewAttachedToWindow(holder);

        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if(lp != null
                && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            p.setFullSpan(holder.getLayoutPosition() == 0);
        }

    }

至此可实现对三种布局的适配,适配器的全部代码如下:



import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.Collections;
import java.util.List;

/**
 * Created by jia on 2017/12/28.
 */

public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder>  {


    private List<ItemInfo>itemLists;
    private View headView;
    private final int HEAD_VIEW_TYPE=1;
    private final int NORMAL_ITEM_TYPE=2;

    public RecycleAdapter(List<ItemInfo> itemLists) {
        this.itemLists = itemLists;
    }

    class ViewHolder extends RecyclerView.ViewHolder{
        ImageView image;
        TextView textView;

        public ViewHolder(View view){
            super(view);
            if (view!=headView) {
                image = view.findViewById(R.id.image);
                textView = view.findViewById(R.id.text);
            }
        }
    }
    @Override
    public RecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType==HEAD_VIEW_TYPE)
            return new ViewHolder(headView);
       View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item,parent,false);
       ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecycleAdapter.ViewHolder holder, int position) {
        if (getItemViewType(position) == HEAD_VIEW_TYPE)
            return;
        try {
            ItemInfo info = itemLists.get(getRealPosition(position));
            holder.textView.setText(info.getTitle());
            holder.image.setImageResource(info.getImgid());
        }catch (Exception e){
            Log.i("jm", "jm--onBindViewHolder: "+position);
        }

    }

    private int getRealPosition(int position){
        if (headView!=null){
            return position-1;
        }

        return position;
    }

    @Override
    public int getItemCount() {
        return headView==null?itemLists.size():itemLists.size()+1;
    }

    @Override
    public int getItemViewType(int position) {
        if (headView!=null&&(position==0)){
            return HEAD_VIEW_TYPE;
        }
        return NORMAL_ITEM_TYPE;
    }


    public void setHeaderView(View view){
        headView=view;
        notifyDataSetChanged();
    }

    public View getHeaderView(){
       return headView;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return getItemViewType(position) == HEAD_VIEW_TYPE
                            ? gridManager.getSpanCount() : 1;
                }
            });
        }
    }

    @Override
    public void onViewAttachedToWindow(ViewHolder holder) {
        super.onViewAttachedToWindow(holder);

        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if(lp != null
                && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            p.setFullSpan(holder.getLayoutPosition() == 0);
        }

    }

}


实现效果如下:

RecycleView使用总结二

三. 使用ItemTouchHelper实现RecycleView活动删除效果

最终要实现的效果如下,录屏软件出现bug,总录制偏。。:

RecycleView使用总结二

ItemTouchHelper的使用时,只需以下几行代码:

   //先实例化Callback
        ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(myAdapter);
        //用Callback构造ItemtouchHelper
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        //调用ItemTouchHelper的attachToRecyclerView方法建立联系
        touchHelper.attachToRecyclerView(recyclerView);

从代码中,可以看出,我们只需要创建一个ItemTouchHelper对象,为其添加一个ItemTouchHelper.Callback接口,然后绑定到RecycleView上即可,具体来讲,就是通过以上绑定,我们就可以在ItemTouchHelper.Callback接口中捕获操作Item的操作,比如拖动和左右抛,在获取到相应操作的时候根据需要实现自己的逻辑,比如获取到左滑时,删除数据源中的一条数据,同时更新adapter,来达到滑动删除的效果。ItemTouchHelper.Callback中提供了很多回调,如下,根据文档注释以及方法名称可很快了解到他们的用途:

RecycleView使用总结二

其中,常用的有如下一些:

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //在这里可以设置哪些方向上支持拖动,滑动等
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        int swipeFlags = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
        return makeMovementFlags(dragFlags,swipeFlags);
    }

    @Override
    public boolean isLongPressDragEnabled() {//返回true:长按后可拖动item,返回false:长按没效果
        return true;
    }

    @Override
    public boolean isItemViewSwipeEnabled() {//返回true:可实现抛动
        return true;
    }
    //onMove方法中,是拖动item的回调,可以获取到拖动的item以及要拖动的位置
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return true;
    }
   //抛动后的回调
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        //对我们正在操作的item进行一些绘制操作,比如变更位置,添加一些额外的变化效果等
    }

除了以上,还可以设置滑动,以及拖动的响应阈值,该值是个比例因子,值越小,操作越灵敏,使用时在回调中直接复写设置相应的值即可:

     /**
         * Returns the fraction that the user should move the View to be considered as swiped.
         * The fraction is calculated with respect to RecyclerView's bounds.
         * <p>
         * Default value is .5f, which means, to swipe a View, user must move the View at least
         * half of RecyclerView's width or height, depending on the swipe direction.
         *
         * @param viewHolder The ViewHolder that is being dragged.
         * @return A float value that denotes the fraction of the View size. Default value
         * is .5f .
         */
        public float getSwipeThreshold(ViewHolder viewHolder) {
            return .5f;
        }

        /**
         * Returns the fraction that the user should move the View to be considered as it is
         * dragged. After a view is moved this amount, ItemTouchHelper starts checking for Views
         * below it for a possible drop.
         *
         * @param viewHolder The ViewHolder that is being dragged.
         * @return A float value that denotes the fraction of the View size. Default value is
         * .5f .
         */
        public float getMoveThreshold(ViewHolder viewHolder) {
            return .5f;
        }

    需要注意是:ItemTouchHelper在实现swipe或者move时都只是视觉上的效果,它告诉我们把谁给滑没了,在哪两个位置上产生了拖动交换的事件,但并没有真实的去处理数据更新显示,它只是告诉我们产生了这个操作,具体处理逻辑还需自己添加,比如执行了swipe操作,如果你不在方法回调中删除对应item的数据,刷新adapter,那么删除的item位置就会留下空白,如下:

RecycleView使用总结二

最后,本篇的全部测试代码如下:

1.MainActivity.java


import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {

    RecyclerView recyclerView;
    private List<ItemInfo>itemList=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView=findViewById(R.id.recycle);
        initDatas();
        LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

        StaggeredGridLayoutManager staggeredGridLayoutManager=new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);

        GridLayoutManager gridLayoutManager=new GridLayoutManager(this,3);
        recyclerView.setLayoutManager(gridLayoutManager);
        RecycleAdapter myAdapter=new RecycleAdapter(itemList);
        recyclerView.scrollToPosition(1);
        recyclerView.addItemDecoration(new CustomItemDecoration());
        recyclerView.setAdapter(myAdapter);
        View headView= LayoutInflater.from(this).inflate(R.layout.head_view_layout,recyclerView,false);
        myAdapter.setHeaderView(headView);

        headView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressDialog progressDialog=new ProgressDialog(MainActivity.this);
                progressDialog.setCanceledOnTouchOutside(false);
                progressDialog.setTitle("测试");
                progressDialog.setMessage("内容");
                progressDialog.setButton(DialogInterface.BUTTON1, "取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(MainActivity.this,"点击了取消",Toast.LENGTH_SHORT).show();
                    }
                });
                progressDialog.show();
                Toast.makeText(MainActivity.this,"点击了headerView",Toast.LENGTH_SHORT).show();
            }
        });
        //先实例化Callback
        ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(myAdapter);
        //用Callback构造ItemtouchHelper
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        //调用ItemTouchHelper的attachToRecyclerView方法建立联系
        touchHelper.attachToRecyclerView(recyclerView);

    }
    void initDatas(){
        for (int i=0;i<40;i++){

            ItemInfo info=new ItemInfo();
            info.setImgid(R.mipmap.ic_launcher);
            info.setTitle("测试"+i);
            itemList.add(info);

        }

    }
}

2.recycleView适配器RecycleAdapter,实现了一个辅助接口ItemTouchHelperAdapter,目的是在ItemTouchHelper.Callback接口中获取到抛动和拖动事件时能够,回调给适配器,进行数据和显示的更新。



/**
 * Created by jia on 2018/5/30.
 */

public interface ItemTouchHelperAdapter {
    //数据交换
    void onItemMove(int fromPosition,int toPosition);
    //数据删除
    void onItemDissmiss(int position);
}



import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.Collections;
import java.util.List;

public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> implements ItemTouchHelperAdapter {


    private List<ItemInfo>itemLists;
    private View headView;
    private final int HEAD_VIEW_TYPE=1;
    private final int NORMAL_ITEM_TYPE=2;

    public RecycleAdapter(List<ItemInfo> itemLists) {
        this.itemLists = itemLists;
    }

    class ViewHolder extends RecyclerView.ViewHolder{
        ImageView image;
        TextView textView;

        public ViewHolder(View view){
            super(view);
            if (view!=headView) {
                image = view.findViewById(R.id.image);
                textView = view.findViewById(R.id.text);
            }
        }
    }
    @Override
    public RecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType==HEAD_VIEW_TYPE)
            return new ViewHolder(headView);
       View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item,parent,false);
       ViewHolder viewHolder=new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecycleAdapter.ViewHolder holder, int position) {
        if (getItemViewType(position) == HEAD_VIEW_TYPE)
            return;
        try {
            ItemInfo info = itemLists.get(getRealPosition(position));
            holder.textView.setText(info.getTitle());
            holder.image.setImageResource(info.getImgid());
        }catch (Exception e){
            Log.i("jm", "jm--onBindViewHolder: "+position);
        }

    }

    private int getRealPosition(int position){
        if (headView!=null){
            return position-1;
        }

        return position;
    }

    @Override
    public int getItemCount() {
        return headView==null?itemLists.size():itemLists.size()+1;
    }

    @Override
    public int getItemViewType(int position) {
        if (headView!=null&&(position==0)){
            return HEAD_VIEW_TYPE;
        }
        return NORMAL_ITEM_TYPE;
    }


    public void setHeaderView(View view){
        headView=view;
        notifyDataSetChanged();
    }

    public View getHeaderView(){
       return headView;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    return getItemViewType(position) == HEAD_VIEW_TYPE
                            ? gridManager.getSpanCount() : 1;
                }
            });
        }
    }

    @Override
    public void onViewAttachedToWindow(ViewHolder holder) {
        super.onViewAttachedToWindow(holder);

        ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
        if(lp != null
                && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
            p.setFullSpan(holder.getLayoutPosition() == 0);
        }

    }

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        //交换位置
        if (getItemViewType(toPosition)==HEAD_VIEW_TYPE) //headView不可交换
            return;
        Collections.swap(itemLists,getRealPosition(fromPosition),getRealPosition(toPosition));
        notifyItemMoved(fromPosition,toPosition);
    }

    @Override
    public void onItemDissmiss(int position) {
        //移除数据
        itemLists.remove(getRealPosition(position));
        notifyItemRemoved(position);
    }


}

3.实现ItemTouchHelper.Callback接口,捕获事件,进行处理


import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;


public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback{

    private ItemTouchHelperAdapter mAdapter;

    public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter){
        mAdapter = adapter;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //head view 不可滑动,拖动
        if (recyclerView.getAdapter().getItemViewType(viewHolder.getAdapterPosition())==1){
            return 0;
        }

        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        int swipeFlags = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
        return makeMovementFlags(dragFlags,swipeFlags);
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
        return super.getSwipeThreshold(viewHolder);
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return true;
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        //mAdapter.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        //mAdapter.onItemDissmiss(viewHolder.getAdapterPosition());
    }

//    @Override
//    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
//
//        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
//            final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
//            //viewHolder.itemView.setAlpha(alpha);
//            //viewHolder.itemView.setTranslationX(dX);
//        }
//
//    }


    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
            viewHolder.itemView.setAlpha(alpha);
            viewHolder.itemView.setTranslationX(dX);
        }
    }
}
4.添加的一个自定义RecyclerView.ItemDecoration


import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class CustomItemDecoration extends RecyclerView.ItemDecoration {

    private static final int HEAD_VIEW_TYPE=1;
    private boolean hasHeadView=false;
    Paint mPaint;
    public CustomItemDecoration() {
        super();
        mPaint=new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);

    }

    /**
     *在itemView绘制之前绘制,所以要通过getItemOffsets设置好距离,留出空间,防止被后绘得的itemView覆盖掉
     * @param c
     * @param parent
     * @param state
     */
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
//        int childCount = parent.getChildCount();
//        for ( int i = 0; i < childCount; i++ ) {
//            View view = parent.getChildAt(i);
//            int index = parent.getChildAdapterPosition(view);
//            float top = view.getBottom();
//            float extra=view.getHeight()/2;
//            c.drawCircle(50, top+extra,20,mPaint);
//        }
    }

    /**
     * 在itemVie上面绘制,根据设计,使用canvas进行绘制即可
     * @param c
     * @param parent
     * @param state
     */
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
        int childCount = parent.getChildCount();//当前可见的Item数,并不一定是全部
        for ( int i = 0; i < childCount; i++ ) {
            View view = parent.getChildAt(i);
            int index = parent.getChildAdapterPosition(view);//获取adpter中对应的位置,获取item类型要使用它
            if (parent.getAdapter().getItemViewType(index)==HEAD_VIEW_TYPE)//headView不绘制
                continue;
            float top = view.getTop();
            float left=view.getLeft();
            float right = view.getRight();
            float bottom=view.getBottom();
            float extra=view.getHeight()/2;
            c.drawCircle(left-20, top+extra,20,mPaint);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setTextSize(15);
            mPaint.setStrokeWidth(1);
            Rect rect=new Rect();
            mPaint.getTextBounds(i+"",0,(i+"").length(),rect);

            c.drawText(i+"",left-20-rect.width()/2,top+extra+rect.height()/2,mPaint);
            c.drawRect(left-10,top-10,right+10,bottom+10,mPaint);
        }

    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        int position=parent.getChildAdapterPosition(view);

        if (parent.getAdapter().getItemViewType(position)!=HEAD_VIEW_TYPE)
            {
                outRect.top = 30;
                outRect.left=30;
        }
    }
}

    至此,本文结束,作者依葫芦画瓢,对recycleView的相关基本使用流程有了一个大致了解,但对具体细节还不清楚,以后需要慢慢深化。

参考(引用)文章:

1.RecyclerView添加Header的正确方式

2.RecyclerView进阶:使用ItemTouchHelper实现拖拽和侧滑删除