RecyclerView作为升级版的ListView和GridView,更加的先进和灵活。接下来就介绍下RecyclerView的用法。
首先,在gradle脚本中添加,

compile 'com.android.support:recyclerview-v7:23.0.1'

在布局中引用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/recyclerview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        /></RelativeLayout>

RecyclerView是没有divider属性的。

Adapter的编写,这里的Adapter应该继承public static abstract class Adapter {},可以看到,这里内部就有一个ViewHolder,我们只需要实现自己的ViewHolder就好,我们必须要实现Adapter的3个方法:

  • onCreateViewHolder 创建holder
  • onBindViewHolder 绑定holder
  • getItemCount 得到view的数目
    最终的代码我会在后面给出。

  • 设置分割线

recyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this, DividerItemDecoration.VERTICAL_LIST));

我们通过addItemDecoration来添加分割线,DividerItemDecoration这个类就是实现分割线的。
这个类我是抄网上的。。。

package gl.com.as;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;/** * Created by mac on 15-10-9. */public class DividerItemDecoration 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 Drawable mDivider;    private int mOrientation;    public DividerItemDecoration(Context context,int orienttation){        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();        setOrientation(orienttation);    }    public void setOrientation(int orientation){        if (orientation!=HORIZONTAL_LIST && orientation!=VERTICAL_LIST){            throw new IllegalArgumentException("invalid orientation");        }        mOrientation=orientation;    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        if (mOrientation==VERTICAL_LIST){            drawVertival(c,parent);        }else{            drawHorizontal(c,parent);        }    }    /** * draw vertival line * @param c * @param parent */    public void drawVertival(Canvas c,RecyclerView parent){        final int left = parent.getPaddingLeft();        final int right = 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+mDivider.getIntrinsicHeight();            mDivider.setBounds(left,top,bottom,right);            mDivider.draw(c);        }    }    /** * draw horizaontal line * @param c * @param parent */    public 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; 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.getIntrinsicWidth();            mDivider.setBounds(left,top,right,bottom);            mDivider.draw(c);        }    }    @Override    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {        if (mOrientation==VERTICAL_LIST){            outRect.set(0,0,0,mDivider.getIntrinsicHeight());        }else{            outRect.set(0,0,mDivider.getIntrinsicWidth(),0);        }    }}

上面的类就实现了横 竖2中分割线,想实现其他样式的参考张鸿洋,

  • LayoutManager
    这里有3种:
    1.LinearLayoutManager(..) listview风格
    2.GridLayoutManager(..) GridView
    3.StaggeredGridLayoutManager(..) 同样可以实现gridview,还可以实现瀑布流,只要设置好高度就行。

  • 添加增加删除动画

recyclerView.setItemAnimator(new DefaultItemAnimator());

这是系统默认的动画,我们当然也可以定制自己的动画啦。具体实现参考DefaultItemAnimator类的实现,不过github上 有很多牛人已经做了很多了。小伙伴们可以去github上找找。Github上的动画

  • 监听器的实现
    RecyclerView没有提供设置监听器的方法 ,不过没关系。我们可以实现自己的回调接口
public interface OnItemClickListener {        void onClick(int pos);        void onLongClick(int pos);    }    private OnItemClickListener listener;    public void setOnclickListener(OnItemClickListener listener){        this.listener=listener;    }   //然后在onBindViewHolder中添加   if (listener!=null){            holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    int pos=holder.getLayoutPosition();                    listener.onClick(pos);                }            });            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    int pos = holder.getLayoutPosition();                    listener.onLongClick(pos);                    return false;                }            });        }

接下来,在Activity中

 mAdapter.setOnclickListener(new RecyclerViewAdapter.OnItemClickListener() {            @Override            public void onClick(int pos) {                Toast.makeText(MainActivity.this,pos+"click",Toast.LENGTH_SHORT).show();            }            @Override            public void onLongClick(int pos) {                Toast.makeText(MainActivity.this,pos+"long click",Toast.LENGTH_SHORT).show();            }        });
  • 多布局的实现
    重写getItemViewType(int pos)方法 ,onCreateViewHolder(ViewGroup parent, int viewType),第二个参数就position对应的type了,我们只需要根据viewType返回不同的viewholder即可。
    下面是Adapter的完整代码
package gl.com.as;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * Created by mac on 15-10-9. */public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{    private Context context;    private List<String> mDatas;    private List<Integer> mHeight;    public RecyclerViewAdapter(Context context,List<String> mDatas){        this.context=context;        this.mDatas=mDatas;        mHeight = new ArrayList<Integer>();        for (int i =0;i<mDatas.size();i++){            mHeight.add((int) (100+Math.random()*300));        }    }    public interface OnItemClickListener {        void onClick(int pos);        void onLongClick(int pos);    }    private OnItemClickListener listener;    @Override    public int getItemViewType(int position) {        if (position%2==0){            return 0;        }else{            return 1;        }    }    public void setOnclickListener(OnItemClickListener listener){        this.listener=listener;    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        ViewHolder holder=null;        Log.e("tag","this is on onCreateViewHolder"+viewType);        switch (viewType){            case 0:                holder = new ViewHolder(LayoutInflater.from(context).inflate(R.layout.rccyclerview_item,parent,false));                break;            default:                holder = new ViewHolder(LayoutInflater.from(context).inflate(R.layout.rccyclerview_item2,parent,false));                break;        }        return holder;    }    @Override    public void onBindViewHolder(final ViewHolder holder, int position) {        ViewGroup.LayoutParams lp = holder.textView.getLayoutParams();        lp.height=mHeight.get(position);        holder.textView.setLayoutParams(lp);        holder.textView.setText(mDatas.get(position));        if (listener!=null){            holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    int pos=holder.getLayoutPosition();                    listener.onClick(pos);                }            });            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    int pos = holder.getLayoutPosition();                    listener.onLongClick(pos);                    return false;                }            });        }    }    @Override    public int getItemCount() {        return mDatas.size();    }    public void addData(int position){        mDatas.add(position,"Insert One");        notifyItemInserted(position);    }    public void removeData(int position){        mDatas.remove(position);        notifyItemRemoved(position);    }    class ViewHolder extends RecyclerView.ViewHolder {        private TextView textView;        public ViewHolder(View itemView) {            super(itemView);            textView= (TextView) itemView.findViewById(R.id.id_text);        }    }}

上图:

  • 下拉刷新和上拉加载更多
    利用SwipeRefreshLayout,因为SwipeRefreshLayout没有上拉加载更多,所以我这里给出大概思路。
<RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <android.support.v4.widget.SwipeRefreshLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_above="@id/image"        >        <android.support.v7.widget.RecyclerView            android:id="@+id/recyclerview"            android:divider="#dddd0000"            android:dividerHeight="10dp"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            />    </android.support.v4.widget.SwipeRefreshLayout>    <ImageView        android:id="@+id/image"        android:layout_width="40dp"        android:layout_height="40dp"        android:src="@mipmap/ic_launcher"        android:visibility="gone"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true" /></RelativeLayout>

其实这里用FrameLayout更好一点,我这里为了省事。下拉刷新实现SwipeRefreshLayout.OnRefreshListener接口就好。上拉刷新的话

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                int lastVisiableItem = ((LinearLayoutManager)manager) .findLastVisibleItemPosition();                if (lastVisiableItem+1==mDatas.size()){                    image.setVisibility(View.VISIBLE);                    //do something                }            }        });

这里是LinearLayoutManager,其他2个的话做相应的逻辑处理。关于SwipeRefreshLayout封装上拉加载更多,网上很多人写了。百度。。。

  • 头部尾部问题
    关于Recycler添加头部尾部问题是在蛋疼。不过好在有ListView,我们可以参考ListView的实现方法来实现。
    以下为ListView的部分源码,以添加headview为例:
private ArrayList<FixedViewInfo> mHeaderViewInfos = Lists.newArrayList();    private ArrayList<FixedViewInfo> mFooterViewInfos = Lists.newArrayList();
public void addHeaderView(View v, Object data, boolean isSelectable) {        final FixedViewInfo info = new FixedViewInfo();        info.view = v;        info.data = data;        info.isSelectable = isSelectable;        mHeaderViewInfos.add(info);        mAreAllItemsSelectable &= isSelectable;        // Wrap the adapter if it wasn't already wrapped.        if (mAdapter != null) {            if (!(mAdapter instanceof HeaderViewListAdapter)) {                mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);            }            // In the case of re-adding a header view, or adding one later on,            // we need to notify the observer.            if (mDataSetObserver != null) {                mDataSetObserver.onChanged();            }        }    }

关键就在于HeaderViewListAdapter。根据HeaderViewListAdapter的代码依葫芦画瓢就行了。小弟在这里就不献丑了。给出参考资料,去看这位大神的代码吧。添加头部尾部
好累,到这里就完了。
参考资料:添加头尾
参考资料:张鸿洋

更多相关文章

  1. Android代码中添加打印信息
  2. 安卓 Android之开发简单小应用(二)
  3. android mtk6592 添加led三色灯,红色蓝色绿色
  4. android Activity关闭动画 附左右动画anim
  5. Android布局管理器-使用TableLayout表格布局管理器实现简单的用
  6. Fragment的使用
  7. AndroidStudio常见问题
  8. flutter的AndroidX版本适配
  9. 十四、ContentProvider往通讯录添加联系人和获取联系人

随机推荐

  1. 自定义实现圆形播放进度条(android,飞一般
  2. android中对服务端的长连接【socket】
  3. android视频开发倍速播放,调整视频播放速
  4. Android静态变量的生命周期
  5. 不容错过!开发者必备的十二大Android开发
  6. Android异步加载全解析之Bitmap
  7. 分享几点Android(安卓)开发中的小技巧
  8. 阿里ctf-2014 android 第三题――so动态
  9. 《Android移动应用基础教程》(Android(安
  10. Android的开源隐忧:品牌稀释 代码分裂