RecyclerView 案例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RecyclerView 案例相关的知识,希望对你有一定的参考价值。
RecyclerView基本使用Demo
MainActivity
public class MainActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"基础,点击下试试",
"添加",
"删除",
"ListView",
"横向的GridView",
"横向瀑布流",
"纵向瀑布流",
"分割线 ItemDecoration",
"BaseRecyclerViewAdapterHelper基本使用"};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
if (position <= 6) {
Intent intent = new Intent(this, RecyclerViewActivity.class);
intent.putExtra("type", position);
startActivity(intent);
} else if (position == 7) {
startActivity(new Intent(this, RV_ItemDecorationActivity.class));
} else if (position == 8) {
startActivity(new Intent(this, BRVAHActivity.class));
}
}
}
RecyclerViewActivity
public class RecyclerViewActivity extends Activity implements MyOnItemClickLitener {
private RecyclerView mRecyclerView;
private MyRecyclerViewAdapter mRecyclerViewAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.rv);
init();
}
protected void init() {
List<String> mDatas = new ArrayList<String>();
for (int i = ‘A‘; i < ‘z‘; i++) {
mDatas.add("" + (char) i);
}
mRecyclerViewAdapter = new MyRecyclerViewAdapter(this, mDatas);
mRecyclerViewAdapter.setOnItemClickLitener(this);
mRecyclerViewAdapter.setMargins(5);//addItemDecoration一会单独拿出来说
mRecyclerView.setAdapter(mRecyclerViewAdapter);//设置adapter
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));//设置布局管理器
mRecyclerView.setItemAnimator(new DefaultItemAnimator());//设置Item增加、移除动画
}
@Override
public void onItemClick(View view, int position) {
Toast.makeText(this, position + " 被点击了", Toast.LENGTH_SHORT).show();
reInit(position);
}
@Override
public void onItemLongClick(View view, int position) {
Toast.makeText(this, position + "被长按了", Toast.LENGTH_SHORT).show();
}
private void reInit(int position) {
int type = getIntent().getIntExtra("type", 0);
switch (type) {
case 0:
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));//添加间隔线
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL));//添加间隔线
break;
case 1:
mRecyclerViewAdapter.addDataAt(position, "添加一条数据\nposition=" + position);
mRecyclerView.scrollToPosition(position);
break;
case 2:
mRecyclerViewAdapter.removeDataAt(position);
mRecyclerView.scrollToPosition(position);//删除最后一条数据时也不会报错
break;
case 3:
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
break;
case 4:
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4, GridLayoutManager.HORIZONTAL, false));//横向的GridView
break;
case 5://Staggered:错列的,叉排的
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1 + new Random().nextInt(8), StaggeredGridLayoutManager.HORIZONTAL));//行
mRecyclerViewAdapter.setRandomWidth(true);
break;
case 6:
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1 + new Random().nextInt(5), StaggeredGridLayoutManager.VERTICAL));//列
mRecyclerViewAdapter.setRandomHeight(true);
break;
}
}
}
MyRecyclerViewAdapter
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
private Context context;
private List<String> mDatas;
private MyOnItemClickLitener mOnItemClickLitener;
private int margins = 0;
private boolean randomWidth = false;
private boolean randomHeight = false;
public MyRecyclerViewAdapter(Context context, List<String> mDatas) {
this.context = context;
this.mDatas = mDatas;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));
}
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.tv.setText(mDatas.get(position));
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.tv.getLayoutParams();
lp.setMargins(margins, margins, margins, margins);//设置边距,这里完全可以放在RecyclerView的addItemDecoration方法中
//横向时,item的宽度需要设置;纵向时,item的高度需要设置
if (randomHeight) lp.height = 200 + new Random().nextInt(5) * 100;//**************************************************唯一的区别在这
if (randomWidth) lp.width = 200 + new Random().nextInt(5) * 100;//***************************************************唯一的区别在这
holder.tv.setLayoutParams(lp);
// 如果设置了回调,则设置点击事件
holder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickLitener != null) mOnItemClickLitener.onItemClick(holder.itemView, holder.getAdapterPosition());
}
});
holder.itemView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnItemClickLitener != null) mOnItemClickLitener.onItemLongClick(holder.itemView, holder.getAdapterPosition());
return false;
}
});
}
@Override
public int getItemCount() {
return mDatas.size();
}
/**
* 添加并更新数据,同时具有动画效果
*/
public void addDataAt(int position, String data) {
mDatas.add(position, data);
notifyItemInserted(position);//更新数据集,注意如果用adapter.notifyDataSetChanged()将没有动画效果
}
/**
* 移除并更新数据,同时具有动画效果
*/
public void removeDataAt(int position) {
mDatas.remove(position);
notifyItemRemoved(position);
}
public void setOnItemClickLitener(MyOnItemClickLitener mOnItemClickLitener) {
this.mOnItemClickLitener = mOnItemClickLitener;
}
public void setMargins(int margins) {
this.margins = margins;
}
public void setRandomWidth(boolean randomWidth) {
this.randomWidth = randomWidth;
}
public void setRandomHeight(boolean randomHeight) {
this.randomHeight = randomHeight;
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;
public MyViewHolder(View view) {
super(view);
tv = (TextView) view.findViewById(R.id.id_num);
}
}
}
MyOnItemClickLitener
/**系统没有提供ClickListener和LongClickListener,我们自己通过接口回调处理 */
public interface MyOnItemClickLitener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
RV_ItemDecorationActivity
public class RV_ItemDecorationActivity extends Activity implements MyOnItemClickLitener {
private RecyclerView mRecyclerView;
private MyRecyclerViewAdapter mRecyclerViewAdapter;
private RecyclerView.ItemDecoration decoration;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.rv);
init();
}
protected void init() {
List<String> mDatas = new ArrayList<String>();
mDatas.add("0.添加VERTICAL间隔线");
mDatas.add("1.添加HORIZONTAL间隔线");
mDatas.add("2.移除VERTICAL间隔线");
mDatas.add("3.recreate");
mDatas.add("4.Horizontal_Divider_ItemDecoration");
mDatas.add("5.Vertical_Divider_ItemDecoration");
mDatas.add("6.不包含边界的空白间隔");
mDatas.add("7.包含边界的空白间隔");
mDatas.add("8.自定义图片间隔 true,false");
mDatas.add("9.自定义颜色间隔 false,true");
mDatas.add("10.显示但不绘制边界间隔");
mDatas.add("11.不绘制左右边界间隔");
mDatas.add("12.不绘制上下边界间隔");
for (int i = ‘A‘; i < ‘z‘; i++) {
mDatas.add("" + (char) i);
}
mRecyclerViewAdapter = new MyRecyclerViewAdapter(this, mDatas);
mRecyclerViewAdapter.setOnItemClickLitener(this);
decoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
mRecyclerView.setAdapter(mRecyclerViewAdapter);//设置adapter
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));//设置布局管理器
mRecyclerView.setItemAnimator(new DefaultItemAnimator());//设置Item增加、移除动画
}
@Override
public void onItemClick(View view, int position) {
Toast.makeText(this, position + " 被点击了", Toast.LENGTH_SHORT).show();
reInit(position);
}
@Override
public void onItemLongClick(View view, int position) {
Toast.makeText(this, position + "被长按了", Toast.LENGTH_SHORT).show();
}
private void reInit(int position) {
switch (position) {
case 0:
mRecyclerView.addItemDecoration(decoration);//添加间隔线
break;
case 1:
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL));
break;
case 2:
mRecyclerView.removeItemDecoration(decoration);//移除间隔线,即使没有添加也可以移除
break;
case 3:
recreate();
break;
case 4://For layout manager having 【vertical orientation】 to draw horizontal divider
mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this)//不能和Vertical*同时使用
.margin(20)//距离【左右】边界的距离margin(leftMargin, rightMargin)
.size(5)//高度
.color(0xff0000ff)
//.drawable(R.mipmap.ic_launcher)//间隔线不使用颜色而使用drawable,color()会把drawable()覆盖掉
.positionInsideItem(false)//间隔线是否绘制在item内容的上面,默认为false
.showLastDivider()//默认不显示最后一条间隔线
.build());
break;
case 5://For layout manager having 【horizontal orientation】 to draw vertical divider
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4, GridLayoutManager.HORIZONTAL, false));
mRecyclerView.addItemDecoration(new VerticalDividerItemDecoration.Builder(this)//不能和Horizontal*同时使用
.margin(20)//距离【上下】边界的距离margin(leftMargin, rightMargin)
.size(5).color(0xff0000ff).build());
break;
case 6:
mRecyclerView.addItemDecoration(new GridItemDecoration.Builder().spanCount(4).spaceSize(1).build());
break;
case 7:
mRecyclerView.addItemDecoration(new GridItemDecoration.Builder().spanCount(4).spaceSize(50)
.includeLREdge(true).includeTBEdge(true).build());//
break;
case 8:
mRecyclerView.addItemDecoration(new GridItemDecoration.Builder().spanCount(4).spaceSize(12)
.includeLREdge(true)
.mDivider(getResources().getDrawable(R.mipmap.ic_launcher)).build());//
break;
case 9:
mRecyclerView.addItemDecoration(new GridItemDecoration.Builder().spanCount(4).spaceSize(6)
.includeTBEdge(true)
.mDivider(new ColorDrawable(0x880000ff)).build());//
break;
case 10:
mRecyclerView.addItemDecoration(new GridItemDecoration.Builder().spanCount(4).spaceSize(50)
.includeLREdge(true).includeTBEdge(true).drawLREdge(false).drawTBEdge(false)
.mDivider(new ColorDrawable(0x880000ff)).build());//
break;
case 11:
mRecyclerView.addItemDecoration(new GridItemDecoration.Builder().spanCount(4).spaceSize(50)
.includeLREdge(true).includeTBEdge(true).drawLREdge(false)
.mDivider(new ColorDrawable(0x880000ff)).build());//
break;
case 12:
mRecyclerView.addItemDecoration(new GridItemDecoration.Builder().spanCount(4).spaceSize(50)
.includeLREdge(true).includeTBEdge(true).drawTBEdge(false)
.mDivider(new ColorDrawable(0x880000ff)).build());//
break;
}
}
}
GridItemDecoration
/**
* 适用于GridView,支持在item之间设置任何类型的间距,支持控制是否显示上下左右间隔及是否绘制上下左右背景
*/
public class GridItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
private int spanCount;
private int spaceSize;
private boolean includeLREdge;
private boolean includeTBEdge;
private boolean drawLREdge;
private boolean drawTBEdge;
private GridItemDecoration(Builder builder) {
mDivider = builder.mDivider;
spanCount = builder.spanCount;
spaceSize = builder.spaceSize;
includeLREdge = builder.includeLREdge;
includeTBEdge = builder.includeTBEdge;
drawLREdge = builder.drawLREdge;
drawTBEdge = builder.drawTBEdge;
}
@Override
public String toString() {
return "GridItemDecoration{" +
"spanCount=" + spanCount +
", spaceSize=" + spaceSize +
", includeLREdge=" + includeLREdge +
", includeTBEdge=" + includeTBEdge +
‘}‘;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view); // item position
int column = position % spanCount; // item column
if (includeLREdge) {
outRect.left = spaceSize - column * spaceSize / spanCount;
outRect.right = (column + 1) * spaceSize / spanCount;
} else {
outRect.left = column * spaceSize / spanCount;
outRect.right = spaceSize - (column + 1) * spaceSize / spanCount;
}
if (includeTBEdge) {
if (position < spanCount) outRect.top = spaceSize; // top edge
outRect.bottom = spaceSize; // item bottom
} else {
if (position >= spanCount) outRect.top = spaceSize; // item top
}
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (mDivider != null) {
drawHorizontal(c, parent);
drawVertical(c, parent);
if (includeLREdge && drawLREdge) drawLR(c, parent);
if (includeTBEdge && drawTBEdge) drawTB(c, parent);
}
}
private void drawLR(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
//最左边那条线
if (i % spanCount == 0) {
int left = child.getLeft() - spaceSize;
int right = left + spaceSize;
int bottom = child.getBottom();
int top = child.getTop() - spaceSize;
if (i == 0) top = child.getTop(); //最上边那条线
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
//最右边那条线
if ((i + 1) % spanCount == 0) {
int left = child.getRight();
int right = left + spaceSize;
int bottom = child.getBottom();
int top = child.getTop() - spaceSize;
if (i == spanCount - 1) top = child.getTop(); //最上边那条线
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
private void drawTB(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
//最上边那条线
if (i < spanCount) {
int top = child.getTop() - spaceSize;
int bottom = top + spaceSize;
int left = child.getLeft();
int right = child.getRight() + spaceSize;
if ((i + 1) % spanCount == 0 ||
(childCount < spanCount && i == childCount - 1)) right = child.getRight(); //最右边那条线
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
//最下边那条线
if (childCount % spanCount == 0 && i >= spanCount * (childCount / spanCount - 1)) {
int top = child.getBottom();
int bottom = top + spaceSize;
int left = child.getLeft() - spaceSize;
int right = child.getRight();
if ((i + 1) % spanCount == 0) right = child.getRight() + spaceSize; //最右边那条线
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
} else if (i >= spanCount * (childCount / spanCount)) {
int top = child.getBottom();
int bottom = top + spaceSize;
int right = child.getRight();
int left = child.getLeft() - spaceSize;
if (!drawLREdge && i % spanCount == 0) left = child.getLeft(); //最左边那条线
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
private void drawHorizontal(Canvas c, RecyclerView parent) {
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
if (i >= spanCount) {
View child = parent.getChildAt(i);
int left = child.getLeft() - spaceSize;
if (i % spanCount == 0) left = child.getLeft();
int right = child.getRight();
int top = child.getTop() - spaceSize;
int bottom = top + spaceSize;
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++) {
if (i % spanCount != 0) {
View child = parent.getChildAt(i);
int top = child.getTop();
int bottom = child.getBottom();
int left = child.getLeft() - spaceSize;
int right = left + spaceSize;
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
static final class Builder {
private Drawable mDivider = null;
private int spanCount;
private int spaceSize;
private boolean includeLREdge = false;
private boolean includeTBEdge = false;
private boolean drawLREdge = true;
private boolean drawTBEdge = true;
public Builder() {
}
/**
* 若不指定,则使用空白代替
*/
public Builder mDivider(Drawable val) {
mDivider = val;
return this;
}
/**
* 行数或列数
*/
public Builder spanCount(int val) {
spanCount = val;
return this;
}
/**
* 行列间距大小
*/
public Builder spaceSize(int val) {
spaceSize = val;
return this;
}
/**
* 是否包含左右边界
*/
public Builder includeLREdge(boolean val) {
includeLREdge = val;
return this;
}
/**
* 是否包含上下边界
*/
public Builder includeTBEdge(boolean val) {
includeTBEdge = val;
return this;
}
/**
* 是否绘制左右边界
*/
public Builder drawLREdge(boolean val) {
drawLREdge = val;
return this;
}
/**
* 是否绘制上下边界
*/
public Builder drawTBEdge(boolean val) {
drawTBEdge = val;
return this;
}
public GridItemDecoration build() {
return new GridItemDecoration(this);
}
}
}
BRVAHActivity
public class BRVAHActivity extends Activity implements BaseQuickAdapter.RequestLoadMoreListener, SwipeRefreshLayout.OnRefreshListener {
private List<String> mDatas;
private RecyclerView mRecyclerView;
private PullToRefreshAdapter mAdapter;
private SwipeRefreshLayout mSwipeRefreshLayout;
private static final int TOTAL_COUNTER = 18;
private static final int PAGE_SIZE = 6;
private static final int DELAY_MILLIS = 1000;
private int mCurrentCounter = 0;
private boolean isErr;
private boolean mLoadMoreEndGone = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeLayout);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189));
mRecyclerView = (RecyclerView) findViewById(R.id.rv);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
initDate();
initAdapter();
ImageView headView = new ImageView(this);
headView.setImageResource(R.mipmap.ic_launcher);
mAdapter.addHeaderView(headView);
}
private void initDate() {
mDatas = new ArrayList<String>();
for (int i = ‘A‘; i < ‘z‘; i++) {
mDatas.add("" + (char) i);
}
}
private void initAdapter() {
mAdapter = new PullToRefreshAdapter();
mAdapter.setOnLoadMoreListener(this, mRecyclerView);
mAdapter.openLoadAnimation(BaseQuickAdapter.SLIDEIN_RIGHT);//动画
mAdapter.setPreLoadNumber(3);//预加载
mRecyclerView.setAdapter(mAdapter);
mCurrentCounter = mAdapter.getData().size();
//item点击事件
mAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
Toast.makeText(BRVAHActivity.this, "onItemClick" + position, Toast.LENGTH_SHORT).show();
}
});
//item中View的点击事件
mAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
Toast.makeText(BRVAHActivity.this, "onItemChildClick" + position, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onLoadMoreRequested() {
mSwipeRefreshLayout.setEnabled(false);
if (mAdapter.getData().size() < PAGE_SIZE) {
mAdapter.loadMoreEnd(true);
} else {
if (mCurrentCounter >= TOTAL_COUNTER) {
//pullToRefreshAdapter.loadMoreEnd();//default visible
mAdapter.loadMoreEnd(mLoadMoreEndGone);//true is gone,false is visible
} else {
if (isErr) {
mAdapter.addData("新数据");
mCurrentCounter = mAdapter.getData().size();
mAdapter.loadMoreComplete();
} else {
isErr = true;
Toast.makeText(BRVAHActivity.this, "错误", Toast.LENGTH_LONG).show();
mAdapter.loadMoreFail();
}
}
mSwipeRefreshLayout.setEnabled(true);
}
}
@Override
public void onRefresh() {
mAdapter.setEnableLoadMore(false);//禁止加载
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mAdapter.setNewData(mDatas);
isErr = false;
mCurrentCounter = PAGE_SIZE;
mSwipeRefreshLayout.setRefreshing(false);
mAdapter.setEnableLoadMore(true);//启用加载
}
}, DELAY_MILLIS);
}
class PullToRefreshAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
public PullToRefreshAdapter() {
super(R.layout.item2, mDatas);
}
@Override
protected void convert(BaseViewHolder helper, String item) {
helper.setText(R.id.id_num, item)
.setImageResource(R.id.iv, R.drawable.actionbar_add_icon)
.addOnClickListener(R.id.iv);
}
}
}
依赖
dependencies {
compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2‘, {
exclude group: ‘com.android.support‘, module: ‘support-annotations‘
})
compile ‘com.android.support:appcompat-v7:25.3.1‘
compile ‘com.android.support:recyclerview-v7:25.3.1‘
testCompile ‘junit:junit:4.12‘
compile ‘com.yqritc:recyclerview-flexibledivider:1.4.0‘
compile ‘com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.17‘
}
附件列表
以上是关于RecyclerView 案例的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Firebase 获取数据到 Recyclerview 中的片段?
为啥 recyclerview$adapter 在片段中为空