您的位置:首页 > 其它

王学岗RecylerView(一)

2016-06-07 19:34 302 查看
RecyclerView是5.0新特性,是google为了替代ListView GridView这些组件,有自己的优点:耦合度很低的插件式组件;自己实现了convertView的重用,节省内存以及显示的速度

因为是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>


使用自己定义的,覆盖系统自己定义的,我们看下运行效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  RecylerVie