王学岗RecylerView(一)
2016-06-07 19:34
302 查看
RecyclerView是5.0新特性,是google为了替代ListView GridView这些组件,有自己的优点:耦合度很低的插件式组件;自己实现了convertView的重用,节省内存以及显示的速度
因为是5.0新特性,需要添加依赖
我就直接在代码里讲解了,代码注解很详细,可以看懂的
先看MaiActivity类:
自定义的适配器
activity_main.xml文件和adapter_item.xml文件
大家敲一遍代码会发现,他和我们前面讲的listview的优化有很多相似之处!
看下运行效果
大家会发现recylerview没有分割线,RecyclerView并没有divider这样的属性!要想设置分割线需要重新抽象类RecyclerView.ItemDecoration;android文档中有一个官方demo;我们可以借用一下。
然后我们在MainActivity里折折分割线
看下效果
这样我们就有分割线了,但是我们也可以使用自己的图片做分割线,我们修改下 DividerItemDecoration的构造方法;
我们就是用系统自带的ic_launcher图片做分割线;看下效果
虽然分割线很丑,但好歹是我们自己的分割下了!
我们先定义一个R.drawable.divider_background文件
修改res\values\styles.xml文件:
使用自己定义的,覆盖系统自己定义的,我们看下运行效果
因为是5.0新特性,需要添加依赖
我就直接在代码里讲解了,代码注解很详细,可以看懂的
先看MaiActivity类:
package com.example.acer.wang_xue_gang_2016_6_5; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private List<String> data; private MyAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //第一步:获取控件 RecyclerView rl_RecylerView = (RecyclerView) findViewById(R.id.rl); //第二步:初始化数据 initData(); //第三部:设置适配器 myAdapter = new MyAdapter(this, data); rl_RecylerView.setAdapter(myAdapter); //第四部:设置布局管理器,与ListView不同的地方——————线性布局管理器,垂直/水平grid布局管理器 //设置线性布局管理器 rl_RecylerView.setLayoutManager(new LinearLayoutManager(this)); //第五步:添加分割线 rl_RecylerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); } public void initData() { data = new ArrayList<String>(); for (int i = 0; i < 100; i++) { data.add("张欣爱我" + i + "生" + i + "世"); } } }
自定义的适配器
package com.example.acer.wang_xue_gang_2016_6_5; 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; /** * @author w_x_g * @time 2016/6/5 16:38 * @note ${TODO} */ //泛型参事需要在类中定义 public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private LayoutInflater layoutInflater; private List<String> listData; public MyAdapter(Context context, List<String> listData) { this.context = context; this.layoutInflater = LayoutInflater.from(context); this.listData = listData; } //创建ViewHolder缓存对象,将adapter_item布局渲染成view对象 @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = layoutInflater.inflate(R.layout.adapter_item, parent, false); //返回值是内部类,需要一个View 的参数,该参数就是条目的view对象 //把渲染的xml布局 交给MyViewHolder就实现了缓存,可以重复利用了 return new MyViewHolder(view); } //将数据与view 绑定 @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.tv_item_textview.setText(listData.get(position)); } @Override public int getItemCount() { return listData.size(); } //在这里实现了缓存, class MyViewHolder extends RecyclerView.ViewHolder { TextView tv_item_textview; public MyViewHolder(View itemView) { super(itemView); //拿到布局的控件,绑定数据的时候需要使用 tv_item_textview = (TextView) itemView.findViewById(R.id.tv_item); } } }
activity_main.xml文件和adapter_item.xml文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#123456" android:text="张欣"/> <android.support.v7.widget.RecyclerView android:id="@+id/rl" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="赵云" /> </LinearLayout>
大家敲一遍代码会发现,他和我们前面讲的listview的优化有很多相似之处!
看下运行效果
大家会发现recylerview没有分割线,RecyclerView并没有divider这样的属性!要想设置分割线需要重新抽象类RecyclerView.ItemDecoration;android文档中有一个官方demo;我们可以借用一下。
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; /* 这个是v7 中的一个sample中的 */ 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) { //获取listDivider属性,该属性可在sdk\platforms\android-23\data\res\values中找到 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 //在RecyclerView的onDraw中执行 public void onDraw(Canvas c, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } /** * 绘制纵向列表时的分隔线 这时分隔线是横着的 * 每次 left相同,top根据child变化,right相同,bottom也变化 * @param c * @param 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); } } /** * 绘制横向列表时的分隔线 这时分隔线是竖着的 * l、r 变化; t、b 不变 * @param c * @param parent */ 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 //预留item间隙 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); } } }
然后我们在MainActivity里折折分割线
//第五步:添加分割线 rl_RecylerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST)); }
看下效果
这样我们就有分割线了,但是我们也可以使用自己的图片做分割线,我们修改下 DividerItemDecoration的构造方法;
public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); // mDivider = a.getDrawable(0);//系统属性中获取,可以在这里修改分割线图片 mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher); a.recycle(); setOrientation(orientation); }
我们就是用系统自带的ic_launcher图片做分割线;看下效果
虽然分割线很丑,但好歹是我们自己的分割下了!
我们先定义一个R.drawable.divider_background文件
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <size android:width="5dp" android:height="5dp"/> <gradient android:centerColor="#00ff00" android:endColor="#0000ff" android:startColor="#ff0000"/> </shape>
修改res\values\styles.xml文件:
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <!--自己定义listDivider,覆盖系统定义的--> <item name="android:listDivider">@drawable/divider_background</item> </style> </resources>
使用自己定义的,覆盖系统自己定义的,我们看下运行效果
相关文章推荐
- Google I/O 2016 RecyclerView的前世今生,原理详解等
- 一篇博客理解Recyclerview的使用
- RecyclerView控件补充
- 王学岗RecylerView( 二 )
- RecyclerView
- RecyclerView使用大全
- RecylerView的基本用法
- 为RecylerView添加item点击事件
- ItemTouchHelper 入门一
- 2016 百度之星 初赛(2A)
- iOS setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key 问题
- Android自定义圆角ImageView 支持网络图片
- CSS长度单位及区别 em ex px pt in
- 安装 ODAC
- JAVA获取系统时间
- 前m大的数(HDU_1280) 计数排序
- android stdio设置主题
- BZOJ 1100 [POI2007]对称轴osi
- if使用
- 【View工作原理】ViewRoot、DecorView、MeasureSpec和LayoutParams