初探RecyclerView开发
2016-12-08 15:24
162 查看
很长时间没有从事android项目开发了,最近一直在看android新的知识,android开发中列表是非常常见的,以前LIstView效果比较单一,扩展多了会影响性能,现在比较火的RecyclerVIew引起了我的兴趣,决定学习一下。很久没写博客了,顺便记录下,以便回顾。
1,RecyclerView简介
RecyclerView是从android5.0版本开始推出的,依赖于support-v7的一款新的组件,功能强大,不仅可以实现原来ListView的线性列表的效果,还可以实现GridView的网格列表效果以及瀑布流的效果,可以分别通过LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager来管理横向或者竖向的滑动效果。通过自定义继承ItemDecoration类来实现分割线的绘制和效果。Adapter里面封装了复用逻辑,返回的是ViewHolder,不是View。另外还添加了可以控制item增删的动态动画效果。
2,入门实践
废话不多说,开始实践。
1)布局
理所当然,打开布局文件,先布局一个RecyclerView控件进去(这里有部分童鞋会发现怎么自动补全里面没有RecyclerView,或者打上去报错,解决方法:在app目录下面的build.gradle文件里面,在“compile 'com.android.support:appcompat-v7:xx.x.x'”下面加一行代码“compile
'com.android.support:recyclerview-v7:xx.x.x'”,然后clean一下project,这个时候就有RecyclerView控件了),设置好宽高铺满。
2)查找组件
在Activity中查找组件,设置属性:
LinearLayoutManager设置是横向还是竖向滑动。
3)自定义适配器
自定义适配器,需要继承Adapter类,面向ViewHolder,但是需要自己定义ViewHolder类。
同时需要实现三个方法:
getItemCount()
这个方法就是返回获得数据的数目。
onCreateViewHolder()
生成每个item的view,封装到ViewHolder里面去,返回ViewHolder。
onBindViewHolder()
适配数据到view中去。
贴上代码:
此时需要在Activity中实例化适配器,绑定适配器到REcyclerView了:
此时运行,就会看到无分割线的列表。
4)自定义分割线
RecyclerView的分割线不像ListView的分割线那样直接配置属性就好了,这里稍微繁琐一点,需要自定义继承ItemDecoration类。
主要要重写三个方法:getItemOffsets(),还有onDraw()和onDrawOver两者其中之一就可以了。
getItemOffsets()
从字面意思就是Item要偏移, 由于我们在Item和Item之间加入了分隔线,线其实本质就是一个长方形,也是用户自定义的,既然线也有长宽高,就画横线来说,上面的Item加入了分隔线,那下面的Item就要往下平移,平移的量就是分隔线的高度。
这里面重要的是要拿到画分割线的坐标,也就是left,top,right,bottom的值。
①首先讲一下忽略item布局里面设置的margin,padding属性,来获取坐标值。
a)竖向的列表,即横向绘制分割线
left:0
right:parent.getWidth()
top:每个item的底部,就是下面的分割线的top,可以通过childView.getBottom()来获取到。
bottom:就是top+想绘制的分割线的高度。
b)横向列表,即竖向绘制分割线
top:0
bottom:parent.getHeight()
left:每个item的右边,就是后面分割线的left,可以通过childView.getRight()来获取到
right:就是left+分割线的宽度
②再来讲下考虑padding,margin属性的获取方法
a)竖向的列表,即横向绘制分割线
left:0+parent.getPaddingLeft()
right:parent.getWidth() - parent.getPaddingRight
top:每个item的底部+底部margin的值,就是下面的分割线的top,可以通过childView.getBottom()来获取到,再加上view的LayoutParams调用bottomMargin。
bottom:就是top+想绘制的分割线的高度。
b)横向列表,即竖向绘制分割线
top:0+parent.getPaddingTop()
bottom:parent.getHeight() - parent.getPaddingBottom()
left:每个item的右边+右边的margin,就是后面分割线的left,可以通过childView.getRight()来获取到,再加上view的LayoutParams调用rightMargin
right:就是left+分割线的宽度
直接上代码:
附上分割线代码:
drawable:
在AppTheme下添加
此时运行,就会发现item下面有华丽丽的分割线了。
5)实现item点击事件
RecyclerView不像ListView有onItemClickListener事件,这里需要自己在Adapter中添加点击事件的监听。
不多说了,再上一次Adapter的代码。
在Activity中添加:
源码地址:http://download.csdn.net/detail/liujibin1836591303/9705656
1,RecyclerView简介
RecyclerView是从android5.0版本开始推出的,依赖于support-v7的一款新的组件,功能强大,不仅可以实现原来ListView的线性列表的效果,还可以实现GridView的网格列表效果以及瀑布流的效果,可以分别通过LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager来管理横向或者竖向的滑动效果。通过自定义继承ItemDecoration类来实现分割线的绘制和效果。Adapter里面封装了复用逻辑,返回的是ViewHolder,不是View。另外还添加了可以控制item增删的动态动画效果。
2,入门实践
废话不多说,开始实践。
1)布局
理所当然,打开布局文件,先布局一个RecyclerView控件进去(这里有部分童鞋会发现怎么自动补全里面没有RecyclerView,或者打上去报错,解决方法:在app目录下面的build.gradle文件里面,在“compile 'com.android.support:appcompat-v7:xx.x.x'”下面加一行代码“compile
'com.android.support:recyclerview-v7:xx.x.x'”,然后clean一下project,这个时候就有RecyclerView控件了),设置好宽高铺满。
2)查找组件
在Activity中查找组件,设置属性:
//查找控件 recyclerview = (RecyclerView) findViewById(R.id.recyclerview); //创建设置布局管理器 LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); recyclerview.setLayoutManager(layoutManager);
LinearLayoutManager设置是横向还是竖向滑动。
3)自定义适配器
自定义适配器,需要继承Adapter类,面向ViewHolder,但是需要自己定义ViewHolder类。
同时需要实现三个方法:
getItemCount()
这个方法就是返回获得数据的数目。
onCreateViewHolder()
生成每个item的view,封装到ViewHolder里面去,返回ViewHolder。
onBindViewHolder()
适配数据到view中去。
贴上代码:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> { private Context mContext; private List<String> data; public RecyclerAdapter(Context context, List<String> d){ mContext = context; data = d; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_lay,parent,false); MyViewHolder vh = new MyViewHolder(view); return vh; } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { holder.tv.setText(data.get(position).toString()); } @Override public int getItemCount() { return data.size(); } class MyViewHolder extends RecyclerView.ViewHolder { public TextView tv; public MyViewHolder(View itemView) { super(itemView); tv = (TextView) itemView.findViewById(R.id.tv); } } }顺便附上item布局的代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="50dp" > <TextView android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="match_parent" android:textSize="20sp" android:textColor="#ffffff" android:background="#999999" /> </LinearLayout>
此时需要在Activity中实例化适配器,绑定适配器到REcyclerView了:
private RecyclerAdapter adapter;
//绑定适配器 adapter = new RecyclerAdapter(this,mData);在这之前记得初始化添加数据集:
private List<String> mData;
mData = new ArrayList<String>(); for(int i = 0;i < 20;i++){ mData.add("第"+i+"行"); }
此时运行,就会看到无分割线的列表。
4)自定义分割线
RecyclerView的分割线不像ListView的分割线那样直接配置属性就好了,这里稍微繁琐一点,需要自定义继承ItemDecoration类。
主要要重写三个方法:getItemOffsets(),还有onDraw()和onDrawOver两者其中之一就可以了。
getItemOffsets()
从字面意思就是Item要偏移, 由于我们在Item和Item之间加入了分隔线,线其实本质就是一个长方形,也是用户自定义的,既然线也有长宽高,就画横线来说,上面的Item加入了分隔线,那下面的Item就要往下平移,平移的量就是分隔线的高度。
这里面重要的是要拿到画分割线的坐标,也就是left,top,right,bottom的值。
①首先讲一下忽略item布局里面设置的margin,padding属性,来获取坐标值。
a)竖向的列表,即横向绘制分割线
left:0
right:parent.getWidth()
top:每个item的底部,就是下面的分割线的top,可以通过childView.getBottom()来获取到。
bottom:就是top+想绘制的分割线的高度。
b)横向列表,即竖向绘制分割线
top:0
bottom:parent.getHeight()
left:每个item的右边,就是后面分割线的left,可以通过childView.getRight()来获取到
right:就是left+分割线的宽度
②再来讲下考虑padding,margin属性的获取方法
a)竖向的列表,即横向绘制分割线
left:0+parent.getPaddingLeft()
right:parent.getWidth() - parent.getPaddingRight
top:每个item的底部+底部margin的值,就是下面的分割线的top,可以通过childView.getBottom()来获取到,再加上view的LayoutParams调用bottomMargin。
bottom:就是top+想绘制的分割线的高度。
b)横向列表,即竖向绘制分割线
top:0+parent.getPaddingTop()
bottom:parent.getHeight() - parent.getPaddingBottom()
left:每个item的右边+右边的margin,就是后面分割线的left,可以通过childView.getRight()来获取到,再加上view的LayoutParams调用rightMargin
right:就是left+分割线的宽度
直接上代码:
public class DividerItemDecoration extends RecyclerView.ItemDecoration { private Context mContext; private Drawable divider; private int mOrientation; private static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; private static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; public static final int [] ATTRS = new int[]{ android.R.attr.listDivider }; public DividerItemDecoration(Context context,int orientation){ super(); mContext = context; mOrientation = orientation; TypedArray ta = context.obtainStyledAttributes(ATTRS); this.divider = ta.getDrawable(0); ta.recycle(); setOrientation(orientation); } //设置屏幕方向 private void setOrientation(int orientation){ if(orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST){ throw new IllegalArgumentException("invalid orientation"); } } //画横线 public void drawHorizontalLine(Canvas c, RecyclerView parent,RecyclerView.State state){ int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int count = parent.getChildCount(); for(int i = 0;i < count;i++){ View view = parent.getChildAt(i); //获取childView的布局信息 RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams(); int top = view.getBottom() + params.bottomMargin; int bottom = top+divider.getIntrinsicHeight(); divider.setBounds(left,top,right,bottom); divider.draw(c); } } //画竖线 public void drawVerticalLine(Canvas c, RecyclerView parent,RecyclerView.State state){ int top = parent.getPaddingTop(); int bottom = parent.getHeight() - parent.getPaddingBottom(); int count = parent.getChildCount(); for(int i = 0;i < count;i++){ View view = parent.getChildAt(i); //获取childview布局信息 RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams(); int left = view.getRight() + params.rightMargin; int right = left + divider.getIntrinsicWidth(); divider.setBounds(left,top,right,bottom); divider.draw(c); } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if(mOrientation == HORIZONTAL_LIST){ //画横线,就是往下偏移一个分割线的高度 outRect.set(0, 0, 0, divider.getIntrinsicHeight()); }else { //画竖线,就是往右偏移一个分割线的宽度 outRect.set(0, 0, divider.getIntrinsicWidth(), 0); } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); if(mOrientation == VERTICAL_LIST){ drawHorizontalLine(c,parent,state); }else{ drawVerticalLine(c,parent,state); } } }
附上分割线代码:
drawable:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#7b7a7a"/> <size android:height="1dp"/> </shape>
在AppTheme下添加
<item name="android:listDivider">@drawable/divider</item>然后在Activity中给RecyclerVIew添加分割线:
//添加自定义分割线 recyclerview.addItemDecoration(new DividerItemDecoration(this,LinearLayoutManager.VERTICAL));
此时运行,就会发现item下面有华丽丽的分割线了。
5)实现item点击事件
RecyclerView不像ListView有onItemClickListener事件,这里需要自己在Adapter中添加点击事件的监听。
//item回调接口 public interface OnItemClickListener{ void OnItemClick(View view,int position); }创建一个对外开放的事件调用:
//开放的点击监听器的方法 public void setOnItemClickListener(OnItemClickListener onItemClickListener){ mOnItemClickListener = onItemClickListener; }
不多说了,再上一次Adapter的代码。
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private Context mContext;
private List<String> data;
private OnItemClickListener mOnItemClickListener;
public RecyclerAdapter(Context context, List<String> d){
mContext = context;
data = d;
}
//item回调接口 public interface OnItemClickListener{ void OnItemClick(View view,int position); }
//开放的点击监听器的方法 public void setOnItemClickListener(OnItemClickListener onItemClickListener){ mOnItemClickListener = onItemClickListener; }
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_lay,parent,false);
MyViewHolder vh = new MyViewHolder(view);
return vh;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.tv.setText(data.get(position).toString());
if(mOnItemClickListener != null){
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnItemClickListener.OnItemClick(holder.itemView,position);
}
});
}
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tv;
public MyViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}
}
在Activity中添加:
adapter.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() { @Override public void OnItemClick(View view, int position) { Toast.makeText(MainActivity.this,"点击了"+position,Toast.LENGTH_SHORT).show(); } });
源码地址:http://download.csdn.net/detail/liujibin1836591303/9705656
相关文章推荐
- Android开发学习之路-RecyclerView使用初探
- 学习Android开发之RecyclerView使用初探
- Hybrid App 开发初探:使用 WebView 装载页面
- Hybrid App 开发初探:使用 WebView 装载页面
- Android开发模板------RecyclerView简介
- 【FastDev4Android框架开发】CardView完全解析与RecyclerView结合使用(三十二)
- 【FastDev4Android框架开发】RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)
- Hybrid App 开发初探:使用 WebView 装载页面
- Android开发--RecyclerView使用
- 【Android开源项目解析】RecyclerView侧滑删除粒子效果实现——初探Android开源粒子库 Leonids
- Android开发之RecyclerView的上拉刷新和下拉加载
- 【FastDev4Android框架开发】实例解析之SwipeRefreshLayout+RecyclerView+CardView(三十五)
- Hybrid App 开发初探:使用 WebView 装载页面
- 用RecyclerView进行瀑布流的开发所需的工程依赖
- Android开发--RecyclerView使用,看AndroidL新特性
- Android开发之RecyclerView的不同position加载不同View详解
- [android游戏开发初学]SurfaceView初探之缓冲区测试
- Android开发--RecyclerView使用,看AndroidL新特性
- Android开发 解决RecyclerView in SwipeRefreshLayout触发下拉刷新的bug
- 【FastDev4Android框架开发】RecyclerView完全解析之打造新版类Gallery效果(二十九)