RecyclerView常用功能解析

来源:互联网 发布:网络攻击的发展趋势是 编辑:程序博客网 时间:2024/06/16 19:34

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

1. RecyclerView常用功能

  • 普通的上下滑动和左右滑动
  • Grid效果上下滑动和左右滑动
  • 瀑布流的上下滑动和左右滑动
  • 添加分割线
  • 去除最后一个item的分割线
  • 添加点击事件
  • 增加和删除item
  • 添加动画
  • 多布局
  • 下拉刷新和上拉加载
  • 添加头布局和脚布局
  • 拖拽排序和侧滑删除
  • 分页加载、上拉加载、添加脚布局DEMO

2. RecyclerView相关类

  • RecyclerView.Adapter :创建子项item布局和绑定数据
  • RecyclerView.ViewHolder :生成子项item的布局
  • RecyclerView.LayoutManager :设置子项item的排列方式
  • RecyclerView.ItemDecoration : 设置子项item的分割线
  • RecyclerView.ItemAnimator : 设置子项item的动画

3. RecyclerView基本实现

  • 依赖:
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
  • 布局:
<?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"    >    <android.support.v7.widget.RecyclerView        android:id="@+id/main_recyclerview"        android:layout_width="match_parent"        android:layout_height="match_parent">    </android.support.v7.widget.RecyclerView></LinearLayout>
  • 设置布局管理器和Adapter
public class MainActivity extends AppCompatActivity {    private RecyclerView mMain_recyclerview;    private List<String> mList;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        initView();        initData();        initAdapter();    }    //初始化控件    private void initView() {        setContentView(R.layout.activity_main);        mMain_recyclerview = (RecyclerView) findViewById(R.id.main_recyclerview);    }    //初始化数据    private void initData() {        mList = new ArrayList<>();        for (int i = 0; i < 10; i++) {            mList.add("纵向和横向滑动");            mList.add("纵向和横向瀑布流");            mList.add("添加头布局和脚布局");            mList.add("下拉刷新和上拉加载");            mList.add("多布局页面");            mList.add("滑动删除");            mList.add("点击事件");            mList.add("添加空布局");            mList.add("添加分割线");        }    }    //初始化Adapter    private void initAdapter() {        //设置布局管理器        mMain_recyclerview.setLayoutManager(new LinearLayoutManager(this));        //初始化和设置Adapter        MainAdapter mainAdapter = new MainAdapter(mList);        mMain_recyclerview.setAdapter(mainAdapter);    }}
  • Adapter:
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {    private List<String> mList;    public MainAdapter(List<String> list) {        mList = list;    }    //创建子项item的布局    @Override    public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_item, parent, false);        return new ViewHolder(view);    }    //给控件设置数据    @Override    public void onBindViewHolder(MainAdapter.ViewHolder holder, int position) {        holder.tv_main.setText(mList.get(position));    }    //子项item的数量    @Override    public int getItemCount() {        return mList.size();    }    //初始化子项控件    static class ViewHolder extends RecyclerView.ViewHolder {        TextView tv_main;        public ViewHolder(View itemView) {            super(itemView);            this.tv_main = itemView.findViewById(R.id.tv_main);        }    }}

4. RecyclerView左右和上下滑动以及瀑布流:

  • 只需修改布局管理器参数即可:
//ListView形式上下滑动:mMain_recyclerview.setLayoutManager(new LinearLayoutManager(this));//左右滑动:LinearLayoutManager magager = new LinearLayoutManager(this);magager.setOrientation(LinearLayoutManager.HORIZONTAL);//Grid形式上下滑动:GridLayoutManager layoutManager = new GridLayoutManager(this,4);//Grid形式左右滑动:GridLayoutManager layoutManager = new GridLayoutManager(this, 4);layoutManager.setOrientation(GridLayoutManager.HORIZONTAL);//瀑布流形式上下滑动:StaggeredGridLayoutManager layoutManager = newStaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL);//瀑布流形式左右滑动:StaggeredGridLayoutManager layoutManager = newStaggeredGridLayoutManager(4, StaggeredGridLayoutManager.HORIZONTAL);

5. ListView形式上下滑动和左右滑动添加分割线:

  • 添加分割线:
mMain_recyclerview.addItemDecoration(new MyDividerItemDecoration(this, MyDividerItemDecoration.VERTICAL_LIST));
  • MyDividerItemDecoration
    ondraw:绘制 getItemOffsets:绘制的区域
public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {    private static final int[] ATTRS = new int[]{            android.R.attr.listDivider    };    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;    private int mOrientation;    private Drawable mDivider;    private int mDividerHeight = 2; //默认是2px    private Paint mPaint;    //绘制默认分割线    public MyDividerItemDecoration(Context context, int orientation) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0); //系统属性中获取        a.recycle();        setOrientation(orientation);    }    /**     * 自定义分割线     *     * @param context     * @param orientation 列表方向     * @param drawableId  分割线图片     */    public MyDividerItemDecoration(Context context, int orientation, int drawableId) {        this(context, orientation);        mDivider = ContextCompat.getDrawable(context, drawableId);        mDividerHeight = mDivider.getIntrinsicHeight();    }    /**     * 自定义分割线     *     * @param context     * @param orientation   列表方向     * @param dividerHeight 分割线高度     * @param dividerColor  分割线颜色     */    public MyDividerItemDecoration(Context context, int orientation, int dividerHeight, int dividerColor) {        this(context, orientation);        mDividerHeight = dividerHeight;        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setColor(dividerColor);        mPaint.setStyle(Paint.Style.FILL);    }    private void setOrientation(int orientation) {        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {            throw new IllegalArgumentException("invalid orientaion");        }        mOrientation = orientation;    }    @Override //在RecyclerView的onDraw中执行    public void onDraw(Canvas c, RecyclerView parent) {        if (mOrientation == VERTICAL_LIST) {            drawVertical(c, parent);        } else {            drawHorizontal(c, parent);        }    }    private void drawHorizontal(Canvas c, RecyclerView parent) {        final int top = parent.getPaddingTop();        final int bottom = parent.getHeight() - parent.getPaddingBottom();        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount-1; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    private 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 < childCount-1; i++) {            final View child = parent.getChildAt(i);            RecyclerView v = new RecyclerView(parent.getContext());            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    @Override    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        if (mOrientation == VERTICAL_LIST) {            outRect.set(0, 0, 0, mDividerHeight);        } else {            outRect.set(0, 0, mDividerHeight, 0);        }    }}

6. Grid和瀑布流形式添加分割线

  • 添加分割线:
mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
  • DividerGridItemDecoration(Grid和瀑布流形式都可用):
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 a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();    }    @Override    public void onDraw(Canvas c, RecyclerView parent, 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; i++)        {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int left = child.getLeft() - params.leftMargin;            final int right = child.getRight() + params.rightMargin                    + mDivider.getIntrinsicWidth();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawVertical(Canvas c, RecyclerView parent)    {        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++)        {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int top = child.getTop() - params.topMargin;            final int bottom = child.getBottom() + params.bottomMargin;            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicWidth();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    private boolean isLastColum(RecyclerView parent, int pos, int spanCount,                                int childCount)    {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager)        {            if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边            {                return true;            }        } else if (layoutManager instanceof StaggeredGridLayoutManager)        {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            if (orientation == StaggeredGridLayoutManager.VERTICAL)            {                if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边                {                    return true;                }            } else            {                childCount = childCount - childCount % spanCount;                if (pos >= childCount)// 如果是最后一列,则不需要绘制右边                    return true;            }        }        return false;    }    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,                              int childCount)    {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager)        {            childCount = childCount - childCount % spanCount;            if (pos >= childCount)// 如果是最后一行,则不需要绘制底部                return true;        } else if (layoutManager instanceof StaggeredGridLayoutManager)        {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            // StaggeredGridLayoutManager 且纵向滚动            if (orientation == StaggeredGridLayoutManager.VERTICAL)            {                childCount = childCount - childCount % spanCount;                // 如果是最后一行,则不需要绘制底部                if (pos >= childCount)                    return true;            } else            // StaggeredGridLayoutManager 且横向滚动            {                // 如果是最后一行,则不需要绘制底部                if ((pos + 1) % spanCount == 0)                {                    return true;                }            }        }        return false;    }    @Override    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());        }    }}

6. RecyclerView去除最后一个item的分割线

  • ListView形式:在上面的分割线绘制部分,我们只绘制了childCount-1个,所以上面的分割线,已经不会绘制最后一条item的分割线了。

  • Grid和瀑布流形式:首先去判断是不是最后一行或者一列,然后在getItemOffsets方法中不绘制底部或者右边,上面的部分已经实现。

7. RecyclerView添加点击事件

  • 处理点击事件,只需要在Adapter中处理即可:
public class PortraitAdapter extends RecyclerView.Adapter<PortraitAdapter.ViewHolder> {    private List<Fruit> mFruitList;    private boolean flag = true;    public PortraitAdapter(List<Fruit> fruitList) {        mFruitList = fruitList;    }    static class ViewHolder extends RecyclerView.ViewHolder {        ImageView fruitImage;        TextView fruitName;        LinearLayout ll_portraitscape;        public ViewHolder(View view) {            super(view);            fruitImage = (ImageView) view.findViewById(R.id.fruit_image);            fruitName = (TextView) view.findViewById(R.id.fruit_name);            ll_portraitscape = (LinearLayout) view.findViewById(R.id.ll_portraitscape);        }    }    @Override    public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_portrait, parent, false);        final ViewHolder holder = new ViewHolder(view);        holder.ll_portraitscape.setOnLongClickListener(new View.OnLongClickListener() {            @Override            public boolean onLongClick(View v) {                new AlertDialog.Builder(v.getContext())                        .setTitle("确认删除吗")                        .setNegativeButton("取消",null)                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                if (flag == true){                                    removeData(holder.getAdapterPosition());                                    flag=false;                                }else{                                    addData(holder.getAdapterPosition());                                    flag=true;                                }                            }                        })                        .show();                return false;            }        });        holder.fruitImage.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Toast.makeText(parent.getContext(),"我是图片短点击",Toast.LENGTH_SHORT).show();            }        });        return holder;    }    @Override    public void onBindViewHolder(final ViewHolder holder, int position) {        Fruit fruit = mFruitList.get(position);        holder.fruitImage.setImageResource(fruit.getImageId());        holder.fruitName.setText(fruit.getName());    }    @Override    public int getItemCount() {        return mFruitList.size();    }    public void addData(int position) {        mFruitList.add(position, new Fruit("Apple", R.drawable.apple_pic));        notifyItemInserted(position);    }    public void removeData(int position) {        mFruitList.remove(position);        notifyItemRemoved(position);    }}只需要在onCreateViewHolder中处理即可,可以很轻松实现子项中任意控件或布局的点击事件。

7. RecyclerView增加和删除item

  • 在Adapter添加两种方法
public void addData(int position) {        mFruitList.add(position, new Fruit("Apple", R.drawable.apple_pic));        notifyItemInserted(position);    }    public void removeData(int position) {        mFruitList.remove(position);        notifyItemRemoved(position);    }
  • 在Adapter中的onCreateViewHolder中的点击事件里面添加动作
holder.ll_portraitscape.setOnLongClickListener(new View.OnLongClickListener() {            @Override            public boolean onLongClick(View v) {                new AlertDialog.Builder(v.getContext())                        .setTitle("确认删除吗")                        .setNegativeButton("取消",null)                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {                            @Override                            public void onClick(DialogInterface dialog, int which) {                                if (flag == true){                                    removeData(holder.getAdapterPosition());                                    flag=false;                                }else{                                    addData(holder.getAdapterPosition());                                    flag=true;                                }                            }                        })                        .show();                return false;            }        });

8. RecyclerView添加动画效果

  • 默认的动画:
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
  • 自定义的动画:
private int mLastPosition;//放在成员变量的位置上if (viewHolder.getAdapterPosition() > mLastPosition) {    ObjectAnimator scaleX = ObjectAnimator.ofFloat(viewHolder.itemView, "scaleX", 0.5f, 1f);    scaleX.start();    mLastPosition = viewHolder.getLayoutPosition();}

说明:实现的方式有很多种,这里介绍一种,就是在RecyclerView的onBindViewHolder中利用属性动画就可以实现非常华丽的效果。

9. RecyclerView多布局

  • 实现多布局最核心的方法就是在Adapter中重写getItemViewType方法:
@Overridepublic int getItemViewType(int position) {    if (mNewsBeanList.get(position).getThumbnail_pic_s03() == null) {        return IMAGE_ONLY_ONE;    } else {        return IMAGE_TWOORTHREE;    }}

说明:判断下布局的不同,返回不同的值,不同的值就代表了不多的布局。

  • 在onCreateViewHolder方法中第二个参数对应的就是上面方法返回的值,我们根据值的不同,填充不同的布局。
@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {    if (viewType == IMAGE_TWOORTHREE) {        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.news_imagethree_item, viewGroup, false);         ImageThreeViewHolder viewHolder = new ImageThreeViewHolder(view);        return viewHolder;    } else {        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.news_imageonly_item, viewGroup, false);        ImageOnlyOneViewHolder viewHolder = new ImageOnlyOneViewHolder(view);        return viewHolder;    }}
  • 不同的布局需要不同的ViewHolder
    static class ImageThreeViewHolder extends RecyclerView.ViewHolder {        private TextView mTv_title;        private ImageView mIv_image01;        private ImageView mIv_image02;        private ImageView mIv_image03;        private TextView mTv_company;        private TextView mTv_time;        private View mItemView;        public ImageThreeViewHolder(View itemView) {            super(itemView);            mItemView = itemView;            mTv_title = itemView.findViewById(R.id.tv_title);            mIv_image01 = itemView.findViewById(R.id.iv_image01);            mIv_image02 = itemView.findViewById(R.id.iv_image02);            mIv_image03 = itemView.findViewById(R.id.iv_image03);            mTv_company = itemView.findViewById(R.id.tv_company);            mTv_time = itemView.findViewById(R.id.tv_time);        }    }    static class ImageOnlyOneViewHolder extends RecyclerView.ViewHolder {        private View mItemView;        private TextView mTv_title;        private TextView mTv_company;        private TextView mTv_time;        private ImageView mIv_image01;        public ImageOnlyOneViewHolder(View itemView) {            super(itemView);            mItemView = itemView;            mTv_title = itemView.findViewById(R.id.tv_title);            mTv_company = itemView.findViewById(R.id.tv_company);            mTv_time = itemView.findViewById(R.id.tv_time);            mIv_image01 = itemView.findViewById(R.id.iv_image01);        }    }
  • onBindViewHolder方法中的第一个参数对应不同的viewholder,我们通过判断,来进行每个元素的写入
@Override    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {        if (viewHolder instanceof ImageThreeViewHolder) {            ((ImageThreeViewHolder) viewHolder).mTv_title.setText(mNewsBeanList.get(position).getTitle());            ((ImageThreeViewHolder) viewHolder).mTv_company.setText(mNewsBeanList.get(position).getAuthor_name());            ((ImageThreeViewHolder) viewHolder).mTv_time.setText(mNewsBeanList.get(position).getDate());            Glide.with(mContext).load(mNewsBeanList.get(position).getThumbnail_pic_s()).into(((ImageThreeViewHolder) viewHolder).mIv_image01);            Glide.with(mContext).load(mNewsBeanList.get(position).getThumbnail_pic_s02()).into(((ImageThreeViewHolder) viewHolder).mIv_image02);            Glide.with(mContext).load(mNewsBeanList.get(position).getThumbnail_pic_s03()).into(((ImageThreeViewHolder) viewHolder).mIv_image03);        } else if (viewHolder instanceof ImageOnlyOneViewHolder) {            ((ImageOnlyOneViewHolder) viewHolder).mTv_title.setText(mNewsBeanList.get(position).getTitle());            ((ImageOnlyOneViewHolder) viewHolder).mTv_company.setText(mNewsBeanList.get(position).getAuthor_name());            ((ImageOnlyOneViewHolder) viewHolder).mTv_time.setText(mNewsBeanList.get(position).getDate());            Glide.with(mContext).load(mNewsBeanList.get(position).getThumbnail_pic_s()).into(((ImageOnlyOneViewHolder) viewHolder).mIv_image01);        }    }

10. RecyclerView 上拉刷新和下拉加载

  • 下拉刷新(借助SwipeRefreshLayout)
    private void initRefresh() {        srRefresh.setColorSchemeResources(R.color.colorPrimary);        srRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {            @Override            public void onRefresh() {                refreshFruits();            }        });    }    private void refreshFruits() {        new Thread(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(2000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        initFruits();                        adapter.notifyDataSetChanged();                        srRefresh.setRefreshing(false);                    }                });            }        }).start();    }    private void initFruits() {        fruitList.clear();        for (int i = 0; i < 50; i++) {            Random random = new Random();            int index = random.nextInt(fruits.length);            fruitList.add(fruits[index]);        }    }

说明:SwipeRefreshLayout设置一个监听器:setOnRefreshListener,onRefresh方法中进行数据更新的操作。
- 上拉加载

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);                if (newState == RecyclerView.SCROLL_STATE_IDLE) {                    if (adapter.isFadeTips() == false && lastVisibleItem + 1 == adapter.getItemCount()) {                        mHandler.postDelayed(new Runnable() {                            @Override                            public void run() {                                updateRecyclerView(adapter.getRealLastPosition(), adapter.getRealLastPosition() + PAGE_COUNT);                            }                        }, 500);                    }                    if (adapter.isFadeTips() == true && lastVisibleItem + 2 == adapter.getItemCount()) {                        mHandler.postDelayed(new Runnable() {                            @Override                            public void run() {                                updateRecyclerView(adapter.getRealLastPosition(), adapter.getRealLastPosition() + PAGE_COUNT);                            }                        }, 500);                    }                }            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();            }        });

说明:recyclerView添加滑动监听器addOnScrollListener,在onScrollStateChanged方法中处理加载的动作。

11. RecyclerView添加头布局和脚布局

添加头布局和脚布局,其实和实现多布局一模一样,不再赘述。

12. RecyclerView拖曳排序和侧滑删除

private void initBind() {        //为RecycleView绑定触摸事件        ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {            @Override            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {                //侧滑删除                int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;                //首先回调的方法 返回int表示是否监听该方向                int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;//拖拽                return makeMovementFlags(dragFlags, swipeFlags);            }            @Override            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {                //滑动事件                Collections.swap(list, viewHolder.getAdapterPosition(), target.getAdapterPosition());                adapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());                return false;            }            @Override            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {                //侧滑事件                list.remove(viewHolder.getAdapterPosition());                adapter.notifyItemRemoved(viewHolder.getAdapterPosition());            }            @Override            public boolean isLongPressDragEnabled() {                //是否可拖拽                return true;            }        });        helper.attachToRecyclerView(recyclerView);    }

11. 分页加载、上拉加载、添加脚布局DEMO

分页加载的核心代码:

private final int PAGE_COUNT = 10;
adapter = new MyAdapter(getDatas(0, PAGE_COUNT), this, getDatas(0, PAGE_COUNT).size() > 0 ? true : false);
private List<String> getDatas(final int firstIndex, final int lastIndex) {        List<String> resList = new ArrayList<>();        for (int i = firstIndex; i < lastIndex; i++) {            if (i < list.size()) {                resList.add(list.get(i));            }        }        return resList;    }    private void updateRecyclerView(int fromIndex, int toIndex) {        List<String> newDatas = getDatas(fromIndex, toIndex);        if (newDatas.size() > 0) {            adapter.updateList(newDatas, true);        } else {            adapter.updateList(null, false);        }    }

Adapter:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    private List<String> datas;    private Context context;    private int normalType = 0;    private int footType = 1;    private boolean hasMore = true;    private boolean fadeTips = false;    private Handler mHandler = new Handler(Looper.getMainLooper());    private static final String TAG = "MyAdapter";    public MyAdapter(List<String> datas, Context context, boolean hasMore) {        this.datas = datas;        this.context = context;        this.hasMore = hasMore;    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (viewType == normalType) {            return new NormalHolder(LayoutInflater.from(context).inflate(R.layout.item, null));        } else {            return new FootHolder(LayoutInflater.from(context).inflate(R.layout.footview, null));        }    }    @Override    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {        if (holder instanceof NormalHolder) {            ((NormalHolder) holder).textView.setText(datas.get(position));        } else {            ((FootHolder) holder).tips.setVisibility(View.VISIBLE);            if (hasMore == true) {                fadeTips = false;                if (datas.size() > 0) {                    ((FootHolder) holder).tips.setText("正在加载更多...");                }            } else {                if (datas.size() > 0) {                    ((FootHolder) holder).tips.setText("没有更多数据了");                    mHandler.postDelayed(new Runnable() {                        @Override                        public void run() {                            ((FootHolder) holder).tips.setVisibility(View.GONE);                            fadeTips = true;                            hasMore = true;                        }                    }, 500);                }            }        }    }    @Override    public int getItemCount() {        return datas.size() + 1;    }    public int getRealLastPosition() {        return datas.size();    }    public void updateList(List<String> newDatas, boolean hasMore) {        if (newDatas != null) {            datas.addAll(newDatas);        }        this.hasMore = hasMore;        notifyDataSetChanged();    }    class NormalHolder extends RecyclerView.ViewHolder {        private TextView textView;        public NormalHolder(View itemView) {            super(itemView);            textView = (TextView) itemView.findViewById(R.id.tv);        }    }    class FootHolder extends RecyclerView.ViewHolder {        private TextView tips;        public FootHolder(View itemView) {            super(itemView);            tips = (TextView) itemView.findViewById(R.id.tips);        }    }    public boolean isFadeTips() {        return fadeTips;    }    public void resetDatas() {        datas = new ArrayList<>();    }    @Override    public int getItemViewType(int position) {        Log.e(TAG,"getItemCount()::"+getItemCount());        Log.e(TAG,"position::"+position);        if (position == getItemCount() - 1) {            return footType;        } else {            return normalType;        }    }}

Activity

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {    private SwipeRefreshLayout refreshLayout;    private RecyclerView recyclerView;    private List<String> list;    private int lastVisibleItem = 0;    private final int PAGE_COUNT = 10;    private LinearLayoutManager mLayoutManager;    private MyAdapter adapter;    private Handler mHandler = new Handler(Looper.getMainLooper());    private static final String TAG = "MainActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initData();        findView();        initRefreshLayout();        initRecyclerView();    }    private void initData() {        list = new ArrayList<>();        for (int i = 1; i <= 40; i++) {            list.add("条目" + i);        }    }    private void findView() {        refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refreshLayout);        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);    }    private void initRefreshLayout() {        refreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light,                android.R.color.holo_orange_light, android.R.color.holo_green_light);        refreshLayout.setOnRefreshListener(this);    }    private void initRecyclerView() {        adapter = new MyAdapter(getDatas(0, PAGE_COUNT), this, getDatas(0, PAGE_COUNT).size() > 0 ? true : false);        mLayoutManager = new LinearLayoutManager(this);        recyclerView.setLayoutManager(mLayoutManager);        recyclerView.setAdapter(adapter);        recyclerView.setItemAnimator(new DefaultItemAnimator());        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);                if (newState == RecyclerView.SCROLL_STATE_IDLE) {                    if (adapter.isFadeTips() == false && lastVisibleItem + 1 == adapter.getItemCount()) {                        mHandler.postDelayed(new Runnable() {                            @Override                            public void run() {                                updateRecyclerView(adapter.getRealLastPosition(), adapter.getRealLastPosition() + PAGE_COUNT);                            }                        }, 500);                    }                    if (adapter.isFadeTips() == true && lastVisibleItem + 2 == adapter.getItemCount()) {                        mHandler.postDelayed(new Runnable() {                            @Override                            public void run() {                                Log.e(TAG, "lastVisibleItem::" + lastVisibleItem);                                Log.e(TAG, "adapter.getItemCount()::" + adapter.getItemCount());                                updateRecyclerView(adapter.getRealLastPosition(), adapter.getRealLastPosition() + PAGE_COUNT);                            }                        }, 500);                    }                }            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();                Log.e(TAG, "lastVisibleItem::" + lastVisibleItem);                Log.e(TAG, "adapter.getItemCount()::" + adapter.getItemCount());            }        });    }    private List<String> getDatas(final int firstIndex, final int lastIndex) {        List<String> resList = new ArrayList<>();        for (int i = firstIndex; i < lastIndex; i++) {            if (i < list.size()) {                resList.add(list.get(i));            }        }        return resList;    }    private void updateRecyclerView(int fromIndex, int toIndex) {        List<String> newDatas = getDatas(fromIndex, toIndex);        if (newDatas.size() > 0) {            adapter.updateList(newDatas, true);        } else {            adapter.updateList(null, false);        }    }    @Override    public void onRefresh() {        refreshLayout.setRefreshing(true);        adapter.resetDatas();        updateRecyclerView(0, PAGE_COUNT);        mHandler.postDelayed(new Runnable() {            @Override            public void run() {                refreshLayout.setRefreshing(false);            }        }, 1000);    }}

详细说明:http://blog.csdn.net/ljcITworld/article/details/70160820

下载地址:https://github.com/OnlyYouMyLove/PullToLoadData-RecyclerView