Android 开发之 RecyclerView相关知识
来源:互联网 发布:哪里买高仿手表知乎 编辑:程序博客网 时间:2024/06/05 08:52
简介
RecyclerView已经出来相当长一段时间了,现在目前开发过程中大部分的列表数据使用的RecyclerView。为什么广泛使用此控件呢,相比ListView的区别在哪里?因为这个控件自身有优化处理,你只需要设置布局填入数据即可,这点比Listview好很多。在布局管理方面,有三种,比listView强太多了。但是也有部分仍旧在使用listview,毕竟listview优化处理好了,简单的数据也是很好的处理的。
RecyclerView涉及到的知识:
1.三种布局管理器:LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager;
2.设置item之间的分割线 ItemDecoration;
3.item的添加和删除动画ItemAnimator。
1. 基本用法和三种布局管理器的使用和效果
recyclerView = (RecyclerView) findViewById(R.id.rc_photo);recyclerView.setLayoutManager(new GridLayoutManager(this,4));//设置布局管理器recyclerView.setItemAnimator(new DefaultItemAnimator());//设置item动画效果recyclerView.addItemDecoration(new DividerGridItemDecoration(this));//设置item的分割线recyclerView.setAdapter(new FirstAdapter());//设置recyclerview的适配器。
适配器的代码;
public class FirstAdapter extends RecyclerView.Adapter{ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.rcv_item_layout, parent, false); MyViewHolder holder=new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if(holder instanceof MyViewHolder) { MyViewHolder mholder= (MyViewHolder) holder; mholder.tv.setText("第 "+list.get(position)+" item"); mholder.tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(MainActivity.this,"点击了"+position,Toast.LENGTH_SHORT).show(); } }); } } @Override public int getItemCount() { return list.size(); } } public class MyViewHolder extends RecyclerView.ViewHolder { public TextView tv; public MyViewHolder(View itemView) { super(itemView); tv = (TextView) itemView.findViewById(R.id.tv_itemcount); } }
1).LinearLayoutManager的使用,效果和listview是一样的,只需要执行下面的代码就可以实现
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setLayoutManager(new GridLayoutManager(this,4));//第二个参数是列数3).StaggeredGridLayoutManager的使用
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));//第一个是列数,第二个是方向
1).线性布局管理器LinearLayoutManager。系统的分割线如下
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);qRecycleView.addItemDecoration(dividerItemDecoration);
这是系统的分割线,但是如果不满意,想自己定义的话也是可以实现的。DividerItemDecoration该实现类可以看到通过读取系统主题中的 Android.R.attr.listDivider作为Item间的分割线
先定义一个shape
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#F00" android:endColor="#0F0" android:centerColor="#00f" android:type="linear"> </gradient> <size android:height="4px"> </size></shape>在把这个shape设置到主题中
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:listDivider">@drawable/shape_itemdecoration</item> </style>
2).但是自定义的这种不能使用到GridLayoutManager上,为了适配,我们必须重写android的DividerItemDecoration这个类,动态的区划item的边界
package com.zwg.xjkb.view;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.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.RecyclerView.LayoutManager;import android.support.v7.widget.RecyclerView.State;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.View;public class DividerGridItemDecoration extends RecyclerView.ItemDecoration{ private static final int[] ATTRS = new int[] { android.R.attr.listDivider }; private Drawable mDivider; public DividerGridItemDecoration(Context context) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); } @Override public void onDraw(Canvas c, RecyclerView parent, State state) { drawHorizontal(c, parent); drawVertical(c, parent); } private int getSpanCount(RecyclerView parent) { // 列数 int spanCount = -1; LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { spanCount = ((StaggeredGridLayoutManager) layoutManager) .getSpanCount(); } return spanCount; } public void drawHorizontal(Canvas c, RecyclerView parent) { 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.getLeft() - params.leftMargin; final int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawVertical(Canvas c, RecyclerView parent) { 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.getTop() - params.topMargin; final int bottom = child.getBottom() + params.bottomMargin; final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicWidth(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) { LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 { return true; } } else if (layoutManager instanceof StaggeredGridLayoutManager) { int orientation = ((StaggeredGridLayoutManager) layoutManager) .getOrientation(); if (orientation == StaggeredGridLayoutManager.VERTICAL) { if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 { return true; } } else { childCount = childCount - childCount % spanCount; if (pos >= childCount)// 如果是最后一列,则不需要绘制右边 return true; } } return false; } private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) { LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { childCount = childCount - childCount % spanCount; if (pos >= childCount)// 如果是最后一行,则不需要绘制底部 return true; } else if (layoutManager instanceof StaggeredGridLayoutManager) { int orientation = ((StaggeredGridLayoutManager) layoutManager) .getOrientation(); // StaggeredGridLayoutManager 且纵向滚动 if (orientation == StaggeredGridLayoutManager.VERTICAL) { childCount = childCount - childCount % spanCount; // 如果是最后一行,则不需要绘制底部 if (pos >= childCount) return true; } else // StaggeredGridLayoutManager 且横向滚动 { // 如果是最后一行,则不需要绘制底部 if ((pos + 1) % spanCount == 0) { return true; } } } return false; } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { int spanCount = getSpanCount(parent); int childCount = parent.getAdapter().getItemCount(); if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部 { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边 { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight()); } }}在这里要给上面写的shape中size节点添加一个width属性,不然无法显示,android:width="4dp"。
3.item的动画效果。
ItemAnimator也是一个抽象类,好在系统为我们提供了一种默认的实现类,期待系统多添加些默认的实现。
// 设置item动画,这个系统的动画效果。mRecyclerView.setItemAnimator(new DefaultItemAnimator());
public void addData(int position) { mDatas.add(position, "Insert One"); notifyItemInserted(position); } public void removeData(int position) { mDatas.remove(position); notifyItemRemoved(position); }
在Activity中添加两个menu
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.id_action_add: mAdapter.addData(1); break; case R.id.id_action_delete: mAdapter.removeData(1); break; } return true; }
系统动画效果还可以,要想更多了动画效果,自己可以搜索。
到此这个控件的基本使用已经完全可以搞定了。
阅读全文
1 0
- Android 开发之 RecyclerView相关知识
- android开发笔记之RecyclerView
- Android开发相关概念知识
- Android开发像素相关知识
- Android测试开发相关知识
- Android 之 Service 相关知识
- Android RecyclerView相关简化
- Android--RecyclerView,SwipeRefreshLayout相关
- android RecyclerView相关
- Android开发之RecyclerView的使用
- Android开发之实现RecyclerView万能适配器
- Android开发之RecyclerView完全解析(一)
- Android开发之RecyclerView全解
- Android 开发之RecyclerView的使用
- Android 开发之 RecyclerView Adapter 模板
- Android开发之滚动控件RecyclerView
- Android界面开发的相关知识
- Android界面开发的相关知识
- CSS入门
- Plugin execution not covered by lifecycle configuration问题
- Windows下利用dlib19.2实现多目标追踪
- Linux--用shell脚本实现菲波那切数列
- 单点登录的三种实现方式
- Android 开发之 RecyclerView相关知识
- JMeter--HTTP(S) 测试脚本录制创建过程 ---上
- Joda-Time 操作常用时间函数
- 虚拟机可以ping同宿主机,宿主机ping不通虚拟机
- bootstrap尝试用法
- linux中crond服务与crontab用法详解
- Vue2.0的改变
- 1148: 组合三位数之一
- Spark获取某个手机号在某个基站下停留的时间和当前手机所在的位置的案例