1.添加依赖:
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
2. MyAdapter继承RecyclerView.Adapter<MyAdapter.MyViewHolder>
回调方法:onCreateViewHolder 创建ViewHolder
回调方法:onBindViewHolder 数据展示
2.1.MyViewHolder 继承 RecyclerView.ViewHolder
MyAdapter 代码如下:
package org.xm.recyclerviewsimple;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import java.util.List;
import java.util.Random;
/**
* Created by yxm2909 on 2016/7/13.
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private static final String TAG = "MyAdapter";
private List<String> datas;
private LayoutInflater inflater;
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
public interface OnItemClickListener {
public void onClick(View parent, int position);
}
public interface OnItemLongClickListener {
public boolean onLongClick(View parent, int position);
}
public void setOnItemClickListener(OnItemClickListener l) {
this.mOnItemClickListener = l;
}
public void setOnItemLongClickListener(OnItemLongClickListener l) {
this.mOnItemLongClickListener = l;
}
public MyAdapter(Context context, List<String> datas) {
this.datas = datas;
inflater = LayoutInflater.from(context);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private View itemView;
private TextView title;
CheckBox checkBox;
public MyViewHolder(View itemView) {
super(itemView);
this.itemView = itemView;
title = (TextView) itemView.findViewById(R.id.rv_main_item_title);
checkBox= itemView.findViewById(R.id.rv_main_checkbox);
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.e(TAG, "create a new item");
MyViewHolder holder = new MyViewHolder(inflater.inflate(R.layout.rv_main_item, parent, false));
return holder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Log.e(TAG, "set value to item:" + position);
holder.title.setText(datas.get(position));
if(position%2==0){
holder.checkBox.setChecked(true);
}else{
holder.checkBox.setChecked(false);
}
int height = Math.abs((new Random().nextInt(200)) );
if (height < 10) {
height += 70;
}
holder.title.setHeight(height);
// 设置点击事件回调
if (mOnItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.onClick(holder.itemView, pos);
}
});
}
// 设置长按 事件回调
if (mOnItemLongClickListener != null) {
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
int pos = holder.getLayoutPosition();
mOnItemLongClickListener.onLongClick(holder.itemView, pos);
return false;
}
});
}
}
@Override
public int getItemCount() {
return datas.size();
}
public void addData(int position, String content){
datas.add(position,content);
}
public void removeData(int position){
datas.remove(position);
}
}
3. mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); // 设置水平滚动
或者:
// 上下文、(水平、垂直滚动方向)、 是否逆序(逆序第一个摆在末尾)
mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
mRecyclerView.scrollToPosition(initData().size()-1); // 滚动到底部
mRecyclerView.setLayoutManager(new GridLayoutManager(this,3)); // 变gridview一行3个
// 瀑布流,StaggeredGridLayoutManager.VERTICAL 垂直滑动 水平摆放4个
// 有问题,因为复用,位置会自动调换
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
3. mMyAdapter = new MyAdapter(MainActivity.this, initData()); // initData()数据源和上下文
4. mRecyclerView.setAdapter(mMyAdapter); // 设置adapter
new Adapter以后Adapter内部会回调 , getItemCount 、onCreateViewHolder、onBindViewHolder 对应方法
6. 设置item、点击长按事件:
// 给chiild item添加点击事件回调到外部
7. item 添加删除
// 设置添加、删除item默认动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mMyAdapter.notifyItemInserted(position); // RecycleView有单独是适配方法,不像ListView要刷新说有的item
MainActivity 代码区域:
package org.xm.recyclerviewsimple;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private RecyclerView mRecyclerView;
private MyAdapter mMyAdapter;
ImageButton ib_top;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ib_top = (ImageButton)findViewById(R.id.ib_top);
mRecyclerView = (RecyclerView) findViewById(R.id.rv_main);
// 默认垂直滚动
// mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
// 上下文、(水平、垂直方向)、 是否逆序(逆序第一个摆在末尾)
mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));
// mRecyclerView.scrollToPosition(initData().size()-1); // 滚动到底部
// mRecyclerView.setLayoutManager(new GridLayoutManager(this,3)); // gridview一行3个
// 瀑布流,StaggeredGridLayoutManager.VERTICAL 垂直滑动 水平摆放4个
// mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
// 只有GridViewManager有这个方法
GridLayoutManager gridLayoutManager=new GridLayoutManager(this,1);
// 设置跨度大小监听
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
Log.e("denganzhi1","position:"+position); // pisiton表示将要显示的item的position
if(position<=10){
//隐藏
ib_top.setVisibility(View.GONE);
}else{
//显示
ib_top.setVisibility(View.VISIBLE);
}
return 1;
}
});
ib_top.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRecyclerView.scrollToPosition(0);
}
});
// mRecyclerView.setLayoutManager(gridLayoutManager);
SystemDivider systemDivider=new SystemDivider(this);
systemDivider.setmOriientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.addItemDecoration(systemDivider);
mMyAdapter = new MyAdapter(MainActivity.this, initData());
mMyAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
@Override
public void onClick(View parent, int position) {
mMyAdapter.addData(position,"add at------new------:"+position);
// // 设置添加、删除item默认动画
// 会在positon前插入
mMyAdapter.notifyItemInserted(position);
// mMyAdapter.notifyItemRangeInserted(int positionStart, int itemCount); // 批量插入
}
});
mMyAdapter.setOnItemLongClickListener(new MyAdapter.OnItemLongClickListener() {
@Override
public boolean onLongClick(View parent, int position) {
// 设置item 的删除
mMyAdapter.removeData(position);
mMyAdapter.notifyItemRemoved(position);
return false;
}
});
mRecyclerView.setAdapter(mMyAdapter);
// mRecyclerView.addItemDecoration(new MyItemDivider(this,R.drawable.rv_main_item_divider));
// 设置添加、删除item默认动画
// mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
private List<String> initData() {
List<String> datas = new ArrayList<String>();
for (int i = 0; i <= 100; i++) {
datas.add("item:" + i);
}
return datas;
}
// 切换为水平,布局切换
SystemDivider dector= null;
public void shuiping(View view){
// 必须要首先 removeItemDecoration
mRecyclerView.removeItemDecoration(dector);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));
dector =new SystemDivider(this);
dector.setmOriientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.addItemDecoration(dector);
}
// 切换为垂直,布局切换
public void chuizhi(View view){
mRecyclerView.removeItemDecoration(dector);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
dector =new SystemDivider(this);
dector.setmOriientation(LinearLayoutManager.VERTICAL);
mRecyclerView.addItemDecoration(dector);
}
}
8. 设置 绘制水平 、垂直 分割线
解决方法: 如果是基本需要,只要下面有分割线条
1、可以字节写到ViewHolder中
2、也可以设置margin ViewHoder的,然后设置背景
实现原理: 继承 RecyclerView.ItemDecoration 首先重写 getItemOffsets 绘制一个Rect矩形
然后 onDraw 指定矩形坐标,根据坐标draw即可 mDivider.setBounds(left,top,right,bottom);
如果是高要求: 水平 滚动左右都需要分 割线????
SystemDivider 分隔线代码区域:
package org.xm.recyclerviewsimple;
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.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* Created by denganzhi on 2020/3/2.
*/
public class SystemDivider extends RecyclerView.ItemDecoration {
private int mOriientation;
public void setmOriientation(int mOriientation) {
if(mOriientation != LinearLayoutManager.VERTICAL && mOriientation != LinearLayoutManager.HORIZONTAL ){
throw new IllegalArgumentException("必须为水平或者垂直方向");
}
this.mOriientation = mOriientation;
}
private int[] attrs=new int[]{
android.R.attr.listDivider
};
private Drawable mDivider;
public SystemDivider(Context context){
// 获取系统分割线的 listDivider
TypedArray typedArray=context.obtainStyledAttributes(attrs);
mDivider=typedArray.getDrawable(0);
typedArray.recycle();
}
// 2. 计算坐标绘制 mDivider.draw(c)
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
// 垂直
// Android Padding 和 div 一样
if(this.mOriientation == LinearLayoutManager.VERTICAL){
int left = parent.getPaddingLeft();
int right = parent.getWidth()-parent.getPaddingRight();
int chiildCount = parent.getChildCount();
for (int i=0;i<chiildCount;i++){
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params= (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin + Math.round(ViewCompat.getTranslationY(child));
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
}else{
int top = parent.getPaddingTop();
int bottom = parent.getHeight()- parent.getPaddingBottom();
int childCount = parent.getChildCount();
for (int i=0;i<childCount;i++){
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params= (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getRight() + params.rightMargin+ Math.round(ViewCompat.getTranslationX(child));
int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left,top,right,bottom);
mDivider.draw(c);
}
}
}
//int left, int top, int right, int bottom
// 1. 设置位置,占位置
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
//垂直滚动, 设置一个RECT占据位置
if(this.mOriientation == LinearLayoutManager.VERTICAL){
outRect.set(0, 0, 0, mDivider.getIntrinsicWidth());
}else{
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
最终效果:
9. 给每一个Item绘制水平 、垂直分隔线 ,原理和 8 相同
styles.xml 中覆盖布局:
item_divider.xml 选在器 /res/drawable下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:width="2dp" android:height="2dp"/>
<solid android:color="#ff0000"/>
</shape>
styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- 替换系统的listDivider -->
<item name="android:listDivider">@drawable/item_divider</item>
</style>
</resources>
MyDivider 代码实现:
package mk.denganzhi.com.myapplication;
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.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* Created by denganzhi on 2020/3/3.
*/
public class MyDivider extends RecyclerView.ItemDecoration {
private int[] attrs=new int[]{
android.R.attr.listDivider
};
private Drawable mDivider;
public MyDivider(Context context){
// 获取系统分割线的 listDivider
TypedArray typedArray=context.obtainStyledAttributes(attrs);
mDivider=typedArray.getDrawable(0);
typedArray.recycle();
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
// 首先 调用自己的onDraw,然后在 绘制下面的
super.onDraw(c, parent, state);
drawVertical(c,parent);
drawHorizontal(c,parent);
// // 绘制底部
}
private void drawHorizontal(Canvas c, RecyclerView parent) {
// 绘制水平间隔线
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getLeft() - params.leftMargin;
int right = child.getRight()+ params.rightMargin;
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private void drawVertical(Canvas c, RecyclerView parent) {
//绘制垂直间隔线(垂直的矩形)
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int left = child.getRight() + params.rightMargin;
int right = left + mDivider.getIntrinsicWidth();
int top = child.getTop() - params.topMargin;
int bottom = child.getBottom() + params.bottomMargin;
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
// 1. 设置一个矩形
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int right = mDivider.getIntrinsicWidth();
int bottom = mDivider.getIntrinsicHeight();
//int left, int top, int right, int bottom)
outRect.set(0,0,right,bottom);
super.getItemOffsets(outRect, view, parent, state);
}
}
MainActivity 中代码:
package mk.denganzhi.com.myapplication;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
MyAdapter myAdapter;
MyDivider myDivider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.rv_main);
mRecyclerView.setLayoutManager(new GridLayoutManager(this,3)); // gridview一行3个
myAdapter = new MyAdapter(MainActivity.this, initData());
mRecyclerView.setAdapter(new MyAdapter(this,initData()));
myDivider = new MyDivider(this);
mRecyclerView.addItemDecoration(myDivider);
}
private List<String> initData() {
List<String> datas = new ArrayList<String>();
for (int i = 0; i <= 100; i++) {
datas.add("item:" + i);
}
return datas;
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private static final String TAG = "MyAdapter";
private List<String> datas;
private LayoutInflater inflater;
public MyAdapter(Context context, List<String> datas) {
this.datas = datas;
inflater = LayoutInflater.from(context);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private View itemView;
private TextView title;
ImageView checkBox;
public MyViewHolder(View itemView) {
super(itemView);
this.itemView = itemView;
title = (TextView) itemView.findViewById(R.id.rv_main_item_title);
checkBox= itemView.findViewById(R.id.rv_main_checkbox);
}
}
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.e(TAG, "create a new item");
MyAdapter.MyViewHolder holder = new MyAdapter.MyViewHolder(inflater.inflate(R.layout.rv_main_item, parent, false));
return holder;
}
@Override
public void onBindViewHolder(final MyAdapter.MyViewHolder holder, final int position) {
Log.e(TAG, "set value to item:" + position);
holder.title.setText(datas.get(position));
}
@Override
public int getItemCount() {
return datas.size();
}
public void addData(int position, String content){
datas.add(position,content);
}
public void removeData(int position){
datas.remove(position);
}
}
}
效果图如下: