一、简介
RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式。它被作为ListView和GridView控件的继承者,在最新的support-V7版本中提供支持。
RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。
总之ListView和GridView能做的RecyclerView都能做,并且能实现瀑布流效果。
二、使用
1、添加依赖
compile 'com.android.support:recyclerview-v7:26.1.0'
2、布局
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
3、准备数据
private ArrayList<String> datas;
//准备数据集合
datas = new ArrayList<>();
for(int i = 0;i < 100;i++){
datas.add("content_"+i);
}
4、设配器
private RecyclerViewAdapter adapter;
adapter = new RecyclerViewAdapter(RecyclerviewActivity.this,datas);
recyclerview.setAdapter(adapter);
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private Context context;
private ArrayList<String> datas;
public RecyclerViewAdapter(Context context, ArrayList<String> datas) {
this.context = context;
this.datas = datas;
}
/**
* 创建View和ViewHolder
* @param parent
* @param viewType
* @return
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(context, R.layout.item_recyclerview,null);
return new ViewHolder(view);
}
/**
* 数据和View绑定
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//根据位置得到对应的数据
String data = datas.get(position);
holder.text.setText(data);
}
/**
* 得到数据的总条数
* @return
*/
@Override
public int getItemCount() {
return datas.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
ImageView icon;
TextView text;
public ViewHolder(View itemView) {
super(itemView);
icon = (ImageView)itemView.findViewById(R.id.icon);
text = (TextView) itemView.findViewById(R.id.text);
}
}
}
item布局:
<LinearLayout
android:padding="5dp"
android:background="@android:color/white"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:padding="8dp"
android:background="#22000000"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon"
android:src="@mipmap/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:textSize="20sp"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:id="@+id/text"
android:text="content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
5、设置LayoutManager(竖向)
recyclerview.setLayoutManager(new LinearLayoutManager(RecyclerviewActivity.this,LinearLayoutManager.VERTICAL,false));
LinearLayoutManager.VERTICAL是横向显示。
第三个参数是正序还是反序显示。
true是反序显示,但是默认是显示item=0,如果是反序又想显示第一条,那么就得设置开始的位置:
recyclerview.setLayoutManager(new LinearLayoutManager(RecyclerviewActivity.this,LinearLayoutManager.VERTICAL,true));
recyclerview.scrollToPosition(datas.size()-1);
三、设置适配器
1、设置List类型
recyclerview.setLayoutManager(new LinearLayoutManager(RecyclerviewActivity.this,LinearLayoutManager.VERTICAL,false));
2、设置Gride类型
recyclerview.setLayoutManager(new GridLayoutManager(RecyclerviewActivity.this,2,GridLayoutManager.VERTICAL,false));
3、设置瀑布流类型
recyclerview.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
四、分割线
参考:https://blog.csdn.net/lmj623565791/article/details/45059587
工具类:
package com.atguigu.android.atguigu.recyclerview;
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;
public class DividerListItemDecoration 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 DividerListItemDecoration(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) {
// Log.e("recyclerview - itemdecoration", "onDraw()");
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);
android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
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);
}
}
}
设置分割线的样式:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:centerColor="#ff00ff00"
android:endColor="#ff0000ff"
android:startColor="#ffff0000"
android:type="linear" />
<size android:height="2dp"/>
</shape>
应用:
<style name="listDividerTheme">
<item name="android:listDivider">@drawable/divider_bg</item>
</style>
这个设置了之后,只要APP里有线的地方都会应用到。
如果只想在某个活动中应用,又不改变这个活动本身的style,需要如下设置:
<style name="listDividerTheme" 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>
<item name="android:listDivider">@drawable/divider_bg</item>
</style>
五、自定义设置item的点击事件
1、在设配器上设置点击事件
class ViewHolder extends RecyclerView.ViewHolder{
ImageView icon;
TextView text;
public ViewHolder(View itemView) {
super(itemView);
icon = (ImageView)itemView.findViewById(R.id.icon);
text = (TextView) itemView.findViewById(R.id.text);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context,datas.get(getLayoutPosition()),Toast.LENGTH_SHORT).show();
}
});
}
}
2、 使用接口,实现类似ListView中的点击事件
在适配器中定义接口:
/**
* 点击recyclerview的某条监听
*/
public interface OnItemClickListener{
/**
* 当recyclerview某个被点击的时候回调
* @param view 点击item的视图
* @param data 点击得到的数据
*/
public void onItemClick(View view,String data);
}
private OnItemClickListener onItemClickListener;
/**
* 设置recyclerview某个监听
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener ){
this.onItemClickListener = onItemClickListener;
}
在 ViewHolder中修改:
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Toast.makeText(context,datas.get(getLayoutPosition()),Toast.LENGTH_SHORT).show();
if(onItemClickListener != null){
onItemClickListener.onItemClick(v, datas.get(getLayoutPosition()));
}
}
});
Activity:
adapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, String data) {
Toast.makeText(RecyclerviewActivity.this,data,Toast.LENGTH_SHORT).show();
}
});
六、删除和增加数据
1、添加数据
public void addData(int position, String data) {
datas.add(0,data);
//刷新
notifyItemInserted(position);
}
2、删除数据
public void removeData(int position) {
datas.remove(position);
//刷新
notifyItemRemoved(position);
}
在activity中调用方法。
设置自动定位到第一条:
recyclerview.scrollToPosition(0);