android中RecyclerView的简单使用(二)——分割线
来源:互联网 发布:mac翻墙代理软件 编辑:程序博客网 时间:2024/06/08 05:15
在上一篇中我们描述了recyclerview的简单使用,实现了横向的recyclerview,运行效果如下图:
若要让其显示为下图所示的效果:
只需将HORIZONTAL修改为VERTICAL如下图箭头所指位置:
看完效果图之后,我们会发现它虽然代替了listview,但是它没有listview中的分割线。当然,这也是我们上篇文章中提到的关于recyclerview的缺点之一:分割线需要自己写。
在ListView中,Google为我们提供了SetDivider(Drawable divider)这样的方法来设置分隔线,那么在RecyclerView中,Google又为我们提供了什么样的方法去添加分隔线呢?通过查看官方文档,它,提供了:addItemDecoration(RecyclerView.ItemDecoration decor)这个方法了设置分隔线,那问题又来了,RecyclerView.ItemDecoration是什么东西呢?(文章结尾部分做出了解释)
那么接下来就将分割线的有关代码贴出来,并将我自己的理解描述一下。
首先先贴代码:
import java.util.ArrayList;import android.os.Bundle;import android.app.Activity;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.support.v7.widget.RecyclerView.ItemDecoration;import android.support.v7.widget.RecyclerView.LayoutParams;import android.support.v7.widget.RecyclerView.State;import android.support.v7.widget.RecyclerView.ViewHolder;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.LayoutInflater;import android.view.Menu;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.TextView;public class MainActivity extends Activity {// 创建集合,存放数据private ArrayList<String> list = new ArrayList<String>();private RecyclerView recyclerView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 查找控件recyclerView = (RecyclerView) findViewById(R.id.rview);// 初始化list集合for (int i = 0; i < 100; i++) {list.add("数据 " + i);} MyAdapter adapter = new MyAdapter(MainActivity.this, list);//将适配器放到recyclerView上//创建线性布局管理者对象LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);//StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2,//RecyclerView.VERTICAL);//通过manager对象设置显示方向manager.setOrientation(RecyclerView.VERTICAL);//将管理者对象给recyclerViewrecyclerView.setLayoutManager(manager);recyclerView.setAdapter(adapter);recyclerView.addItemDecoration(new MyDecor(MainActivity.this, RecyclerView.VERTICAL));}}class MyAdapter extends RecyclerView.Adapter<ViewHolder> {// 声明两个属性,接收传递过来的数据private Context context;private ArrayList<String> list;private MyViewHolder viewHolder;// 创建一个构造方法,将数据和activity的上下文传递过来public MyAdapter(Context context, ArrayList<String> list) {this.context = context;this.list = list;}// 返回显示的条目个数@Overridepublic int getItemCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic void onBindViewHolder(ViewHolder arg0, int arg1) {// 将父类的对象强转为子类对象// MyViewHolder myViewHolder = (MyViewHolder) arg0;if (arg0 instanceof MyViewHolder) {viewHolder = (MyViewHolder) arg0;}String ss = list.get(arg1);viewHolder.textView.setText(ss);}// 创建viewholder对象,并将对象返回@Overridepublic ViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {View view = LayoutInflater.from(context).inflate(R.layout.re, null);ViewHolder viewHolder = new MyViewHolder(view);return viewHolder;}class MyViewHolder extends ViewHolder {TextView textView;public MyViewHolder(View view) {super(view);textView = (TextView) view.findViewById(R.id.tview);}}}class MyDecor extends ItemDecoration {//定义一个水平和竖直常量private final int Horization = RecyclerView.HORIZONTAL;private final int Vertical = RecyclerView.VERTICAL;//创建一个int型的数组,在数组中存放android中自带的分割线private int [] attrs = {android.R.attr.listDivider};//声明一个图片对象private Drawable drawable;//声明一个RecyclerView的方向private int oritation;public MyDecor (Context context,int orization){TypedArray array = context.obtainStyledAttributes(attrs);drawable = array.getDrawable(0);//让这个属性重复使用array.recycle();//判断方向if (orization != Horization && orization != Vertical) {//如果既不是水平又不是竖直的,抛出异常throw new IllegalArgumentException("没有该方向");}else {oritation = orization;}}@Overridepublic void onDraw(Canvas c, RecyclerView parent, State state) {// TODO Auto-generated method stubsuper.onDraw(c, parent, state);if (oritation == Vertical) {drawHor(c, parent);}}@Override@Deprecatedpublic void getItemOffsets(Rect outRect, int itemPosition,RecyclerView parent) {// TODO Auto-generated method stubsuper.getItemOffsets(outRect, itemPosition, parent);}//新建一个方法,在水平方向画一条线public void drawHor(Canvas canvas,RecyclerView recyclerView){int left = recyclerView.getPaddingLeft();int right = recyclerView.getWidth()-recyclerView.getPaddingRight();int childCount = recyclerView.getChildCount();for (int i = 0; i < childCount; i++) {View child = recyclerView.getChildAt(i);//获取item上view视图的参数对象RecyclerView.LayoutParams params = (LayoutParams) child.getLayoutParams();//根据参数对象获取参数值int top =child.getBottom() + params.bottomMargin; //设置bottom坐标int bottom = top + drawable.getIntrinsicHeight();drawable.setBounds(left, top, right, bottom);//画到花板上drawable.draw(canvas);}}}
这个就是画分割线的方法,我在这里用了内部类的写法,但是不建议这种写法,这样写代码不仅繁杂,还不规范。
在mainactivity中就是进行一系列的查找控件和一些属性的设置,adapter其实和上一篇是一致的,重要的部分就是MyDecor类。
说到这个MyDecor类,就要说一下ItemDecoration
ItemDecoration该类为抽象类,官方目前并没有提供默认的实现类
里面封装了三个方法: (1)void getItemOffsets () (2)void onDraw () (3)void onDrawOver ()
onDraw方法先于drawChildren
onDrawOver在drawChildren之后,一般我们选择复写其中一个即可。
getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量,主要用于绘制Decorator。
当我们调用mRecyclerView.addItemDecoration()方法添加decoration的时候,RecyclerView在绘制的时候,去会绘制decorator,即调用该类的onDraw和onDrawOver方法。
我们使用recyclerview的时候,如果没有设置显示条目的margin,或者padding的话,是没有分割线效果的。 那么除去使用margin或padding,其余的方法是用itemdecoration绘制分割线我们绘制分割线的时候通常会使用drawable去绘制,那个drawable是怎么得到的呢?
方法1:可以使用android自带的属性:android.R.attr.listDivider属性可以获得,那么获得drawable的方法是:
首先获得TypedArray对象,这个是存储属性的一个容器,得到方法是
context.obtainStyledAttributes(int类型数组)
private int[]mDrawableId={android.R.attr.listDivider};
TypedArray ta = mContext.obtainStyledAttributes(mDrawableId);
然后,在从这个属性容器中去得到对应得drawable得到方法是:
Drawable mDrawable=ta.getDrawable(0);
然后再通过重写ItemDecoration中的onDrawOver的方法去书写你的分割线即可。
我现在拿画横线来说,从上面这个图中,我们很容易就可以看到,我们画分隔线的位置,是在每一个Item的布局之间。
我们确定了画在哪里,那我们怎么确定画线的具体的坐标位置呢?也就是我们要确定:分隔线的left, top, right, Bottom. 在Adapter中,我们很容易通过parent(这个parent它其实就是我们能看到的部分)获取每一个childView: (1)left:parent.getPaddingLeft() (2)right: parent. getWidth()-parent.getPaddingRight(); (3)top : 就是红线的上面:我们通过ChildView.getBottom()来得到这个Item的底部的高度,也就是蓝线位置,蓝线和红线之间间距:就是这个Item布局文件的:layout_marginBottom, 然后top的位置就是两者之和。 (4)bttom: 就是top加上分隔线的高度:top+线高。
以上就是recyclerview设置分割线的介绍。
效果图如下:
不足之处请多指教!!!
- android中RecyclerView的简单使用(二)——分割线
- Android RecyclerView的使用(二)——添加分割线
- RecyclerView中ItemDecorationd的简单使用(二)---为item设置分割线
- Android RecyclerView 详解(四) RecyclerView分割线的使用和分割线样式
- RecyclerView-FlexibleDivider—RecyclerView分割线的Android类库
- Android Recyclerview分割线
- android recyclerview分割线
- RecyclerView简单使用之自定义RecyclerView分割线
- 【Android】RecyclerView的分割线ItemDecoration
- Android recyclerView的自定义分割线
- RecyclerView的分割线
- recyclerView的分割线
- recyclerview的分割线
- RecyclerView的分割线
- RecyclerView的分割线
- RecyclerView分割线——万能分割线
- RecyclerView详解 —— 自定义分割线
- Android RecyclerView添加分割线
- Universal-Image-Loader源码收获
- Unsupported major.minor version 52.0异常
- .NET Reflector Visual Studio Extension
- hdu 3401 单调队列优化dp
- target-action
- android中RecyclerView的简单使用(二)——分割线
- Yii学习笔记1-介绍和详细运行过程
- Caffe在Windows上的搭建
- 使用比较器对Treemap按照key进行排序
- Kotlin 学习资源
- ERROR 1045 (28000):Access denied for user 'root'@'localhost' (using password: NO) Mac解决方案
- zxing二维码生成扫描,识别二维码图片,长按识别二维码调用方便简洁
- 第七届蓝桥杯决赛 C语言B组 题解 第五题_广场舞
- 搭建JEESZ分布式架构2--CentOs下安装Tomcat7(环境准备)