RecyclerView

来源:互联网 发布:黑色星期五海淘 知乎 编辑:程序博客网 时间:2024/06/07 02:08

先给大家看一下效果:

这里写图片描述

个人关于RecyclerView的理解

RecyclerView 是Android 版本中新添加的一个用来取代ListView、GridView的SDK,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现不同的效果。

1.RecyclerView特性: 
        1)Item的显示位置,如何显示,通过LayoutManager设置 
        2)Item间的分割通过ItemDecoration设置 
        3)Item增加与删除的动画通过ItemAnimator设置(系统提供一种默认动画效果DefaultItemAnimator,可以自定义动画效果) 
        4)仅仅关注如何回收与复用view

2.RecyclerView相关的重要类 
        Adapter、ViewHolder、LayoutManager、ItemDecoration、ItemAnimator

        Adapter:包装数据集合并且为每个条目创建视图。 
        ViewHolder:保存用于显示每个数据条目的子View。 
        LayoutManager:将每个条目的视图放置于适当的位置。 
        ItemDecoration:在每个条目的视图的周围或上面绘制一些装饰视图。 
        ItemAnimator:在条目被添加、移除或者重排序时添加动画效果。

3.RecyclerView的功能 
       1)竖向listview的风格 (依赖LayoutManager) 
       2)横向listview的风格 (依赖LayoutManager) 
       3)竖向gridview的风格 (依赖LayoutManager) 
       4)横向gridview的风格 (依赖LayoutManager) 
       5)瀑布流 (依赖LayoutManager) 
       6)定制Item增加与删除动画 (依赖ItemAnimator)

下面就看一下关于它的简单的使用吧:

添加的依赖: compile ‘com.android.support:recyclerview-v7:21.0.+’

item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_margin="3dp"    android:background="@drawable/item_selector"    android:layout_height="72dp">    <TextView        android:id="@+id/item_text"        android:layout_width="72dp"        android:layout_height="match_parent"        android:gravity="center"        /></RelativeLayout>

activity_main.xml布局:

<LinearLayout 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"    android:background="#22ff0000"    tools:context=".MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/my_recycler_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:scrollbars="vertical"/></LinearLayout>

瀑布流效果的实现和其他效果的实现只是Adapter有一点不一样,先来看一下其它几种效果的实现:

RecyclerView.ViewHolder的基本作用是缓存视图对象; 
RecyclerView.Adapter还没有默认实现,以后可能会添加。由于RecyclerView.Adapter是一个抽象类,所以必须要实现以下三个方法: 
        - public VH onCreateViewHolder(ViewGroup parent, int viewType) 
        - public void onBindViewHolder(VH holder, int position) 
        - public int getItemCount()

其中VH是泛型类,当继承RecyclerView.Adapter时需要使用具体的类来替换。RecyclerViewAdapter 的示例代码如下:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{    protected List<String> mListData;    private Context mContext;    public RecyclerViewAdapter(Context context,List<String> datas){        this.mListData = datas;        this.mContext = context;        mLayoutInflater = LayoutInflater.from(mContext);    }    //创建ViewHolder    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View v = mLayoutInflater.inflate(R.layout.item,parent,false);        ViewHolder viewHolder = new ViewHolder(v);        return viewHolder;    }    //绑定ViewHolder    @Override    public void onBindViewHolder(final ViewHolder holder, final int position) {        holder.mTextView.setText(mListData.get(position));    }    @Override    public int getItemCount() {        return mListData.size();    }    class ViewHolder extends RecyclerView.ViewHolder{        TextView mTextView;        public ViewHolder(View itemView) {            super(itemView);            mTextView = (TextView) itemView.findViewById(R.id.item_text);        }    }}


RecyclerView的Adapter和之前使用的listview的Adapter还是有相同之处的,所以使用起来并不陌生;

MainActivity.Java

mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);//填充数据mRecyclerViewAdapter = new RecyclerViewAdapter(mContext,mListData);//设置adaptermRecyclerView.setAdapter(mRecyclerViewAdapter);//设置listview垂直如何显示mLinearLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);//创建默认的线性布局LinearlayoutmRecyclerView.setLayoutManager(mLinearLayoutManager);//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能mRecyclerView.setHasFixedSize(true);//添加动画mRecyclerView.setItemAnimator(new DefaultItemAnimator());//绘制分割线mRecyclerView.addItemDecoration(new DividerItemDecoration(mContext, DividerItemDecoration.VERTICAL_LIST));

  • RecyclerView.LayoutManager该类负责放置所有的子View到适当位置。该类有一个默认的实现:LinearLayoutManager,当要实现水平或垂直列表时可以使用该类;
  • RecyclerView.ItemAnimator设置动画,可以进行自定义动画;
  • RecyclerView.ItemDecoration设置item之间的分割线,操作如下:

DefaultItemAnimator.java

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 orientation) {        //从  获取分割线样式        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();        setOrientation(orientation);    }    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) {        if (mOrientation == VERTICAL_LIST) {            drawVertical(c, parent);        } else {            drawHorizontal(c, parent);        }    }    /**     *     * 绘制垂直分割线     *     * */    public 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; 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, right, bottom);            mDivider.draw(c);        }    }    /**     *     * 绘制水平分割线     *     * */    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.getIntrinsicHeight();            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);        }    }}

divider.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <size android:height="2dp"/>    <gradient android:startColor="#ff00ff00" android:centerColor="#ff0000ff" android:endColor="#ffff0000"/>

编写分割线样式

最后操作style.xml: 
这里写图片描述 
分割线就添加完成了,效果如下: 
这里写图片描述 
效果还挺不错的吧。一般我们可能不会用到,因为在item中直接添加View比这种方式简单多了,嘻嘻。

完成这些之后,实现其他几种效果就是设置不同的LayoutManager样式了,代码如下:

//ListViewcase R.id.action_listview:    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));    break;//GridViewcase R.id.action_gridview:    mRecyclerView.setLayoutManager(new GridLayoutManager(this,3));    break;//水平GridVIewcase R.id.action_hor_gridview:    mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(5,StaggeredGridLayoutManager.HORIZONTAL));    break;

现在我们就完成了垂直、水平的ListView和垂直、水平的GridView的效果了,感觉还不错;

由于RecyclerView没有提供点击事件,所以学要我们自己来实现,代码如下:

//定义接口public interface OnItemClickListener{    void onItemClick(View v,int position);    void onItemLongClick(View v,int position);}public void setOnItemClickListener(OnItemClickListener listener){    this.mOnItemClickListener = listener ;}

在绑定ViewHolder的时候去触发:

//绑定ViewHolder @Override public void onBindViewHolder(final ViewHolder holder, final int position) {     holder.mTextView.setText(mListData.get(position));     setOnListtener(holder); } //触发 protected void setOnListtener(final RecyclerView.ViewHolder holder){     if(mOnItemClickListener != null){         holder.itemView.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 int layoutPosition = holder.getPosition();                 mOnItemClickListener.onItemClick(holder.itemView,layoutPosition);             }         });         holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {             @Override             public boolean onLongClick(View v) {                 int layoutPosition = holder.getPosition();                 mOnItemClickListener.onItemLongClick(holder.itemView,layoutPosition);                 return false;             }         });     } }

点击事件:

mRecyclerViewAdapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListener() {    @Override    public void onItemClick(View v, int position) {        Toast.makeText(mContext, "onclick  " + position, Toast.LENGTH_SHORT).show();    }    @Override    public void onItemLongClick(View v, int position) {        Toast.makeText(mContext, "onlongclick  " + position, Toast.LENGTH_SHORT).show();    }});

点击效果就完成了,添加和删除Item效果如下:

//添加布局public void add(int pos){    mListData.add(pos,"add"+pos);    notifyItemInserted(pos);}//删除布局public void delete(int pos){    mListData.remove(pos);    notifyItemRemoved(pos);}


注意: 
1.添加item的时候使用notifyItemInserted(position); 

移除item的时候使用notifyItemRemoved(position); 而不是notifidatasetchanged();

接下来我们就看看瀑布流的实现

瀑布流的原理就是给每个item重新设置宽和高: 

StaggeredRecyclerViewAdapter.java

//绑定ViewHolder@Overridepublic void onBindViewHolder(StaggeredRecyclerViewAdapter.ViewHolder holder, int position) {    LayoutParams lp = holder.itemView.getLayoutParams();    lp.height = mHeights.get(position);    holder.itemView.setLayoutParams(lp);    holder.mTextView.setText(mListData.get(position));    setOnListtener(holder);}

再设置显示方式:

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

瀑布流的效果就实现了!

RecyclerView最基本的使用就讲完了,大家肯定了解BGARefreshLayout这个刷新控件,下一篇博客我会讲解RecyclerView+BGARefreshLayout实现下拉刷新、自定义上拉加载和侧滑删除的效果,先给大家看一下效果图:

这里写图片描述 
还不错吧!

GitHub下载地址: 

https://github.com/fengmaolian/RecyclerView



转载自:http://blog.csdn.net/csdnfml/article/details/49999023

0 0
原创粉丝点击