在项目中我们经常用到recyclerView来实现各种列表。RecyclerView相对于LIstView的优点:
1.RecyclerView封装了ViewHolder的回收复用
2.提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示,RecyclerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。
3.可以控制Item的增删动画,可以通过ItemAnimator这个类控制
下面介绍一下RecyclerVeiw的基本用法。
首先我们要gradle的依赖库中添加
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
在activity_main.xml中添加控件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
新建一个布局文件,作为item布局
recyclerview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_item"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@color/colorAccent"/>
<TextView
android:id="@+id/tv_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
Recyclerview的主要有四个步骤,
1.设置Adapter
2.设置布局管理器
3.设置item分割线
4.设置item增删动画
/**
* 设置Adapter
*/
mRecyclerView.setAdapter(mListAdapter);
/**
* 设置布局管理器
*/
mRecyclerView.setLayoutManager(linearLayoutManager);
/**
* 设置item分割线
*/
mRecyclerView.addItemDecoration(itemDecoration);
/**
* 设置item动画
*/
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
RecyclerView.Adapter需要实现3个方法
1.onCreateViewHolder() 用来展现视图和它的持有者
2.onBindViewHolder() 主要用来把数据绑定到视图上。
3.getItemCount() 返回item的数量
package rv.hq.com.recyclerviewdemo;
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 asus on 2018/3/27.
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private List<String> data;
private Context mContext;
private LayoutInflater mInflater;
public MyAdapter(Context context, List<String> mData){
this.mContext = context;
this.data = mData;
this.mInflater = LayoutInflater.from(context);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate (R.layout.recyclerview_item,parent, false);
MyViewHolder viewHolder = new MyViewHolder (view);
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(data.get(position));
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
private TextView textView;
public MyViewHolder(View view){
super(view);
textView = view.findViewById(R.id.tv_item);
}
}
}
RecyclerView常用的布局管理器有三种:
1.LinearLayoutManager:展示了水平或者垂直的滚动列表,相当于之前学习的ListView,但是没有页眉和页尾。
2.GridLayoutManager:在网格中展示条目,相当于之前学习的GridView。
3.StaggeredGridLayoutManager: 在错落的网格中展示条目,比如常见的瀑布流。
系统给我们提供了一个叫做ItemDecoration的抽象类,却并没有提供它的实现类供我们使用,所以我们必须通过自定义它去使用它,这里我就不重复造轮子啦,网上有很多现成的ItemDecoration的实现类,我们挑一个比较好用的来实现分割线效果:
package rv.hq.com.recyclerviewdemo;
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 asus on 2018/3/27.
*/
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);
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);
}
}
}
最后在MainActivity.class里设置
package rv.hq.com.recyclerviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
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 RecyclerView mRecyclerView;
private MyAdapter adapter;
private List<String> data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.rv);
initData();
adapter = new MyAdapter(MainActivity.this,data);
mRecyclerView.setAdapter(adapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.addItemDecoration(new DividerItemDecoration (this,
DividerItemDecoration.VERTICAL_LIST));
}
private void initData(){
data = new ArrayList<>();
for(int i = 0;i < 6;i++){
data.add("测试数据"+i);
}
}
}
最后如图效果:
在简单介绍了recyclerView的线性布局之后,我们来了解下网格布局和常见的瀑布流布局。
其实和线性布局差不多,主要是布局管理器的改变,和一些属性的使用。
一.网格布局
网格布局管理器--GridLayoutManager
只需将布局管理进行修改,就可以变成网格状了,如下:
//mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setLayoutManager(new GridLayoutManager(this,4))
二.瀑布流式的布局
瀑布流布局管理器--StaggeredGridLayoutManager
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
demo下载:https://download.csdn.net/download/hua93/10312269