RecycleView使用总结二

一. 摘要

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

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

二. 为RecycleView添加headerView

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

    private ListitemLists;
    private View headView;
    private final int HEAD_VIEW_TYPE=1;
    private final int NORMAL_ITEM_TYPE=2;

    public RecycleAdapter(List 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使用总结二_第1张图片             RecycleView使用总结二_第2张图片

  对此,我们需要针对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  {


    private ListitemLists;
    private View headView;
    private final int HEAD_VIEW_TYPE=1;
    private final int NORMAL_ITEM_TYPE=2;

    public RecycleAdapter(List 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使用总结二_第3张图片

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

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

RecycleView使用总结二_第4张图片

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使用总结二_第5张图片

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

    @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.
         * 

* 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使用总结二_第6张图片

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

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 ListitemList=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 implements ItemTouchHelperAdapter {


    private ListitemLists;
    private View headView;
    private final int HEAD_VIEW_TYPE=1;
    private final int NORMAL_ITEM_TYPE=2;

    public RecycleAdapter(List 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实现拖拽和侧滑删除

你可能感兴趣的:(Android学习笔记)