笔记13 RecycleView
来源:互联网 发布:企鹅媒体平台登录mac 编辑:程序博客网 时间:2024/06/16 17:34
那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。
- 你想要控制其显示的方式,请通过布局管理器LayoutManager
- 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
- 你想要控制Item增删的动画,请通过ItemAnimator
- 你想要控制点击、长按事件,请自己写(擦,这点尼玛。)
//设置布局管理器
mRecyclerView.setLayoutManager(layout);
//设置adapter
mRecyclerView.setAdapter(adapter)
//设置Item增加、移除动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//添加分割线
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.HORIZONTAL_LIST));
RecyclerView.LayoutManager吧,这是一个抽象类,好在系统提供了3个实现类:
- LinearLayoutManager 现行管理器,支持横向、纵向。
- GridLayoutManager 网格布局管理器
- 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
- 笔记13 RecycleView
- RecycleView的问题笔记
- RecycleView和CardView笔记(一)
- Android学习笔记--RecycleView用法
- recycleView
- RecycleView
- RecycleView
- RecycleView
- RecycleView
- RecycleView
- RecycleView
- recycleview
- RecycleView
- RecycleView
- RecycleView
- RecycleView
- RecycleView
- recycleview
- POJ Pots 3414 (bfs)
- Selenium2学习笔记二
- 2016多校第四场 HDU5769
- Lua os标准库 - 操作系统处理(operating system facilities)
- ②BeautifulSoup基础知识
- 笔记13 RecycleView
- WPAD
- 二叉树相隔最远的俩点距离
- OpenCV 特征描述
- jquery验证框架
- 题目277 车牌号
- hdu 3874 树状数组 离线处理
- Caffe编译 Mnist训练测试
- MySQL进阶(六)——存储引擎