笔记13 RecycleView

来源:互联网 发布:企鹅媒体平台登录mac 编辑:程序博客网 时间:2024/06/16 17:34


那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

  • 你想要控制其显示的方式,请通过布局管理器LayoutManager
  • 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
  • 你想要控制Item增删的动画,请通过ItemAnimator
  • 你想要控制点击、长按事件,请自己写(擦,这点尼玛。)
mRecyclerView = findView(R.id.id_recyclerview);

//设置布局管理器

mRecyclerView.setLayoutManager(layout);

//设置adapter

mRecyclerView.setAdapter(adapter)

//设置Item增加、移除动画

mRecyclerView.setItemAnimator(new DefaultItemAnimator());

//添加分割线

mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.HORIZONTAL_LIST));


RecyclerView.LayoutManager吧,这是一个抽象类,好在系统提供了3个实现类:

  1. LinearLayoutManager 现行管理器,支持横向、纵向。
  2. GridLayoutManager 网格布局管理器
  3. StaggeredGridLayoutManager 瀑布就式布局管理器


http://blog.csdn.net/lmj623565791/article/details/45059587; 
推荐【张鸿洋的博客】



demo一粒  注释相当的全面 以供以后参考使用

RecycleAdapter

package com.example.ban.myapplication;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.List;/** * Created by ban on 2016/11/24. * <p> * 创建适配器类继承RecycleView的Adapter,步骤为: * <p> * 1、继承RecyclerView.Adapter,并且在Adapter里面声明ViewHolder类继承RecyclerView * .ViewHolder,最后把自己的ViewHolder类丢进自己的Adapter类的泛型中去。 * 2、在自定义ViewHolder类的构造方法中可以通过ID找到布局的控件,控件需要声明为自定义ViewHolder类的成员变量。 * 3、实现RecyclerView.Adapter的所有未实现的函数,onCreateViewHolder主要负责加载布局 * (加载的时候注意要把父布局写到参数里去),创建自定义ViewHolder * 类的对象;onBindViewHolder主要负责把数据设置到Item的控件中;getItemCount主要负责得到数据的数目。 * 4、最好把数据声明为成员变量,在构造函数里面传进来。 * 5、由于RecycleView原生不支持点击事件,需要自己添加接口进行回调。 */public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.MyViewHolder> {    List<String> mDatas = null;    Context mContext = null;    //构造方法,这里还是和使用BaseAdapter的行为习惯一直    //通过构造函数把要显示的数据读取进来    public RecycleAdapter(List<String> mDatas, Context mContext) {        this.mDatas = mDatas;        this.mContext = mContext;    }    /**     * 创建泛型中的ViewHolder的方法     *     * @param parent   父布局     * @param viewType Item类型,根据类型可以指定不同的显示布局,重写getItemViewType()方法     * @return 泛型中的ViewHolder对象     * <p>     * 补充:关于viewType     * 可以通过Adapter的getViewType(int position)方法实现多种不同的条目。     * 具体做法是根据position的不同例如奇数偶数,或者特定值,然后根据viewType参数的不同去inflate不同的item布局即可     */    //负责加载布局   //相当于ListView中的getView()方法    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //加载布局的时候需要注意要把parent传进去        return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout                .item_view, parent, false));    }    /**     * 创建完成ViewHolder之后需要进行绑定,相当于为每个Item进行赋值,绘制Item的     *     * @param holder   onCreateViewHolder()方法创建出来的泛型中的ViewHolder     * @param position 位置     */    // 把数据设置到item的控件中  //在这里需要设置显示的数据    @Override    public void onBindViewHolder(MyViewHolder holder, int position) {        holder.tv_num.setText(mDatas.get(position));    }    /**     * 获取条目数量     *     * @return 数量     */    //主要负责得到数据的数目。    @Override    public int getItemCount() {        return mDatas.size();    }    //自定义ViewHolder必须继承RecyclerView.ViewHolder,在构造函数中进行ID绑定控件,条目监听等    public class MyViewHolder extends RecyclerView.ViewHolder {        TextView tv_num;        public MyViewHolder(final View itemView) {            super(itemView);            tv_num = (TextView) itemView.findViewById(R.id.tv);            tv_num.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View view) {                    if (onItemClickListener != null) {                        onItemClickListener.onItemClick(itemView, getLayoutPosition(), mDatas.get                                (getLayoutPosition()));                    }                }            });        }    }    //自定义监听    private OnItemClickListener onItemClickListener;    //定义一个接口    public interface OnItemClickListener {        void onItemClick(View v, int position, String data);    }    public void setOnItemClickListener(OnItemClickListener listener) {        this.onItemClickListener = listener;    }    public void addData(int position, String data) {        mDatas.add(position, data);        notifyItemInserted(position);    }    public void removeData(int position) {        mDatas.remove(position);        notifyItemRemoved(position);    }}

RecycleDemoActivity

package com.example.ban.myapplication;import android.app.Activity;import android.os.Bundle;import android.support.v7.widget.DefaultItemAnimator;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.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * Created by ban on 2016/11/24. * Activity中需要处理的核心的步骤 * <p> * 1、通过ID找到RecyclerView。 * 2、RecyclerView设置Adapter。 * 3、RecyclerView设置布局管理器,常用的布局管理器有LinearLayoutManager:线性布局, * 4、LayoutManager的实现类,类型包括Vertical和HorizontalGridLayoutManager;格子布局,继承自LinearLayoutManager * ,实现效果类似GridView;StaggeredGridLayoutManager交错的格子布局,同样也是LayoutManager的实现类,类型包括Vertical * 和Horizontal,与GridLayoutManager很相似,不过是交错的格子,也就是宽高不等的格子视图,类似瀑布流的效果。 * 5、RecyclerView设置数据插入、删除的时候的动画效果,这里使用默认的。下面的网址是GitHub上面的开源动画效果: * https://github.com/gabrielemariotti/RecyclerViewItemAnimators * 6、RecyclerView设置Item之间的装饰器,这里也是使用GitHub提供的装饰器,代码会在附件中给出。 */public class RecycleDemoActivity extends Activity {    List<String> datas = null;    private RecyclerView recyclerView;    private RecycleAdapter myAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.recycle);        initData();        recyclerView = (RecyclerView) findViewById(R.id.recycleview);        //设置RecycleView的适配器        myAdapter = new RecycleAdapter(datas, this);        recyclerView.setAdapter(myAdapter);        //设置布局管理器,以渲染出不同的效果        recyclerView.setLayoutManager(new LinearLayoutManager(this));        //设置插入、删除数据的动画效果(这里使用默认的动画)        recyclerView.setItemAnimator(new DefaultItemAnimator());        //设置每个Item之间的装饰(这里设置为分隔线)        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration                .VERTICAL_LIST));        myAdapter.setOnItemClickListener(new RecycleAdapter.OnItemClickListener() {            @Override            public void onItemClick(View v, int position, String data) {                Toast.makeText(RecycleDemoActivity.this, data, Toast.LENGTH_SHORT).show();            }        });    }    private void initData() {        datas = new ArrayList<>();        for (int i = 0; i < 300; i++) {            datas.add(i + "===");        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.menu_main, menu);        return super.onCreateOptionsMenu(menu);    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId()) {            case R.id.action_add:                myAdapter.addData(0, "new data");                recyclerView.scrollToPosition(0);                break;            case R.id.action_delete:                myAdapter.removeData(0);                break;            case R.id.action_gridview:                recyclerView.setLayoutManager(new GridLayoutManager(this, 4));                break;            case R.id.action_listview:                recyclerView.setLayoutManager(new LinearLayoutManager(this));                break;            case R.id.action_staggeredgridview:                recyclerView.setLayoutManager(new StaggeredGridLayoutManager(6,                        StaggeredGridLayoutManager.VERTICAL));                break;        }        return true;    }}

DividerGridItemDecoration

package com.example.ban.myapplication;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.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.View;/** * Created by ban on 2016/11/24. */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());        }    }}

DividerItemDecoration

package com.example.ban.myapplication;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 ban on 2016/11/24. */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);            android.support.v7.widget.RecyclerView v = new android.support.v7.widget.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);        }    }    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);        }    }}

源码地址:http://download.csdn.net/detail/u010566681/9692767




0 0
原创粉丝点击