Android开发--RecyclerView使用,看AndroidL新特性,android5.0新特性

来源:互联网 发布:紫微斗数排盘网络中国 编辑:程序博客网 时间:2024/06/03 04:37

在去年Google I/0大会,Google开放了一个全新的视图类RecyclerView,它被用来代替ListView以及GridView,提供更为高效的回收复用机制,同时实现管理与视图的解耦合,今天对这个新的控件来进行一次总结。

概述

首先,让我们来看一下RecyclerView类之下都有哪些重要的类,以及他们的作用:

  • RecyclerView.Adapter:托管数据集合,为每个Item创建视图;
  • RecyclerView.ViewHolder:承载Item视图的子视图;
  • RecyclerView.LayoutManager:负责Item视图的布局;
  • RecyclerView.ItemDecoration:为每个Item视图添加子视图,在Demo中被用来绘制Divider;
  • RecyclerView.ItemAnimator:负责添加、删除数据时的动画效果;

基本用法

首先让我来看一下RecyclerView的基本用法:

1.创建一个线性布局管理器LayoutManager

// 创建一个线性布局管理器mLayoutManager = new LinearLayoutManager(this);// 默认是Vertical,可以不写mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);mRecyclerView.setLayoutManager(mLayoutManager);

2.重新一个adapter继承RecyclerView.Adapter《VH》,VH就表示我们平时在ListView中用的ViewHolder类(该类必须继承RecyclerView.ViewHolder);

在adapter中有几个重要的方法需要我们自己补充:

  • public int getItemCount():返回显示Item总数;
  • public void onBindViewHolder(ViewHolder vh, int position):绑定View到Item上vh就是我们在继承RecyclerView.Adapter传入的VH类型,在这个方法中处理数据显示到Item上;
  • public ViewHolder onCreateViewHolder(ViewGroup view, int position):在该方法中我们创建一个ViewHolder并返回,ViewHolder必须有一个带有View的构造函数,这个View就是我们Item的根布局,在这里我们可以自定义Item的布局;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {    private List<String> dataList;    public MyAdapter(List<String> list) {        this.dataList = list;    }    @Override    public int getItemCount() {        // TODO Auto-generated method stub        return dataList.size();    }    @Override    public void onBindViewHolder(ViewHolder viewHolder, int position) {        // TODO Auto-generated method stub        viewHolder.textView.setText(dataList.get(position));    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {        // TODO Auto-generated method stub        View view = LayoutInflater.from(viewGroup.getContext()).inflate(                R.layout.item, null);        ViewHolder holder = new ViewHolder(view);        return holder;    }    public class ViewHolder extends RecyclerView.ViewHolder {        public TextView textView;        public ViewHolder(View view) {            super(view);            // TODO Auto-generated constructor stub            textView = (TextView) view.findViewById(R.id.item_text);        }    }}

3.设置数据集

List<String> list = new ArrayList<String>();for (int i = 0; i < 100; i++) {    list.add("item  "+ i);}MyAdapter adapter = new MyAdapter(list);mRecyclerView.setAdapter(adapter);

改变LinearLayoutManager的方向可以设置为横向的ListView显示,这也是RecyclerView的强大之处,可以实现回收管理和视图的解耦。

mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

如何为Item添加分割线

简单的使用之后我们看到的RecyclerView连基本的分割线都没有,接下来就来看看如何为它添加分割线吧:使用addItemDecoration方法可以为RecyclerView添加一个ItemDecoration,利用ItemDecoration为我们绘制分割线。

ItemDecoration下有三个方法,ItemDecoration并没有对其实现,需要我们自己完成:

  • onDraw方法:其绘制将会在每个Item被绘制之前进行;
  • onDrawOver:在绘制完Item后进行绘制;
  • getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量;

让我们来看看代码:

public class ItemDivider extends ItemDecoration {    private Drawable mDrawable;    public ItemDivider(Context context, int resId) {        //在这里我们传入作为Divider的Drawable对象        mDrawable = context.getResources().getDrawable(resId);    }    @Override    public void onDrawOver(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; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            //以下计算主要用来确定绘制的位置            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDrawable.getIntrinsicHeight();            mDrawable.setBounds(left, top, right, bottom);            mDrawable.draw(c);        }    }    @Override    public void getItemOffsets(Rect outRect, int position, RecyclerView parent) {        outRect.set(0, 0, 0, mDrawable.getIntrinsicWidth());    }}

在这里我写了一个shape来代替分割线:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle" >    <solid android:color="#000" />    <size android:height="2dp" /></shape>

添加分割线的效果:

如何添加点击事件 ##

在Adapter中设置自己OnItemClickListener以及OnItemLongClickListener 
在ViewHolder中公开Item的根布局View,之后在onBindViewHolder方法获得根布局View并设置点击的listener,调用自己设置的listener

1.首先在MyAdapter中创建自己的接口:

public interface OnItemClickListener {    public void onClick(View parent, int position);}public interface OnItemLongClickListener {    public boolean onLongClick(View parent, int position);}

2.接着在ViewHolder中将根布局View公开:

public class ViewHolder extends RecyclerView.ViewHolder {        public TextView textView;        public View itemView;        public ViewHolder(View view) {            super(view);            // TODO Auto-generated constructor stub            itemView = view;            textView = (TextView) view.findViewById(R.id.item_text);        }    }
3.最后在onBindViewHolder对itemView设置点击事件:

iewHolder.itemView.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                // TODO Auto-generated method stub                if (onItemClickListener != null) {                    onItemClickListener.onClick(v, position);                }            }        });viewHolder.itemView.setOnLongClickListener(new OnLongClickListener() {            @Override            public boolean onLongClick(View v) {                // TODO Auto-generated method stub                if (onItemLongClickListener != null) {                    return onItemLongClickListener.onLongClick(v, position);                }                return false;            }        });

如何判断是否滑动到达尾部或顶部

LinearLayoutManager提供了如下几个方法来帮助开发者获取屏幕上的顶部item和底部item: 
findFirstVisibleItemPosition() 
findFirstCompletelyVisibleItemPosition() 
findLastVisibleItemPosition() 
findLastCompletelyVisibleItemPosition()

这样我们就得到了思路:对RecyclerView设置滑动监听事件,在其中进行判断:

mRecyclerView.setOnScrollListener(new OnScrollListener() {    boolean isShowTop = false;    boolean isShowBottom = false;    @Override    public void onScrolled(int arg0, int arg1) {        // TODO Auto-generated method stub        if (mLayoutManager.findLastCompletelyVisibleItemPosition() == 99) {            if (!isShowTop) {                Toast.makeText(MainActivity.this, "滑动到底部",                        Toast.LENGTH_SHORT).show();            }            isShowTop = true;        } else {            isShowTop = false;        }        if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {            if (!isShowBottom) {                Toast.makeText(MainActivity.this, "滑动到顶部",                        Toast.LENGTH_SHORT).show();            }            isShowBottom = true;        } else {            isShowBottom = false;        }    }    @Override    public void onScrollStateChanged(int arg0) {        // TODO Auto-generated method stub    }});

来看一下效果:

添加或移除数据

RecyclerView.Adapter中提供了两个方法来做出添加数据或删除数据的调整: 
public final void notifyItemInserted(int position) 
public final void notifyItemRemoved(int position)

这样我们只需在自己的Adapter中提供添加或删除的方法,并在方法之中调用上述方法即可:

 public void insert(String data, int position){        dataList.add(position, data);        notifyItemInserted(position);    }    public void remove(int position){        dataList.remove(position);        notifyItemRemoved(position);    }

接下来我在Activity中对RecyclerView设置点击添加数据,长按删除数据;

 adapter.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onClick(View parent, int position) {                // TODO Auto-generated method stub                adapter.insert("Insert", position);            }        });        adapter.setOnItemLongClickListener(new OnItemLongClickListener() {            @Override            public boolean onLongClick(View parent, int position) {                // TODO Auto-generated method stub                adapter.remove(position);                return true;            }        });

来看一下效果吧:

ItemAnimator可以设置加载和移除时的动画,我们可以通过setItemAnimator方法设置,但目前只提供了DefaultItemAnimator。

转自:http://www.bkjia.com/Androidjc/988765.html

0 0