RecyclerView
简单的了解RecyclerView的使用,对于更深层次的用法,可以查阅文档,或者在网上查询相关资料,以后再有机会,可以进行探讨和分享。
RecyclerView控件简介
- ListView控件的升级版
- LinearLayoutManager
- GridLayoutManager
- StaggeredGridLayoutManager
- 订制Item,指定Item之间的分隔条
RecyclerView的使用
- 更新Android Support Library到最新版本,拷贝\extras\android\support\v7\recyclerview\libs\文件夹下的android-support-v7-recyclerview.jar到项目中。
- 继承ItemDecoration,实现自定义的分割线。由于RecyclerView的布局不固定,因此没有像ListView那样直接设定divider的方式。
- 继承RecyclerView.Adapter,实现适配器。这个只要写过ListView的应该都很明白。
- 创建出RecyclerView控件,对RecyclerView进行设置。
代码实例
- 继承ItemDecoration
package com.example.materialdesign.recyclerview;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ItemDecoration;
import android.support.v7.widget.RecyclerView.LayoutParams;
import android.support.v7.widget.RecyclerView.State;
import android.view.View;
//由于RecyclerView的布局不固定,因此没有像ListView那样直接设定divider的方式,这些可能需要自己实现
public class SampleDriver extends ItemDecoration {
// 系统自带的分隔条的资源
private static final int[] ATTRS = { android.R.attr.listDivider };
// 分隔条对象
private final Drawable mDrawable;
public SampleDriver(Context context) {
TypedArray array = context.obtainStyledAttributes(ATTRS);
mDrawable = array.getDrawable(0);
// 回收TypedArray所占用的空间
array.recycle();
}
// 绘制所有列表项之间的分隔条
@Override
public void onDrawOver(Canvas c, RecyclerView parent, State state) {
// 获取列表项距离左边缘的间距
int left = parent.getLeft();
// 获取列表项距离右边缘的间距
int right = parent.getWidth() - parent.getPaddingRight();
// 获取列表项总数
int childCount = parent.getChildCount();
// 开始绘制所有列表项之间的分割线
for (int i = 0; i < childCount; i++) {
// 获得当前的列表项
View child = parent.getChildAt(i);
// 获取当前列表项的布局参数信息
RecyclerView.LayoutParams parentpParams = (LayoutParams) child.getLayoutParams();
// 计算分隔条左上角的纵坐标
int top = child.getBottom() + parentpParams.bottomMargin;
// 计算分隔条右下角的纵坐标
int bottom = top + mDrawable.getIntrinsicHeight();
// 设置分隔条绘制的位置
mDrawable.setBounds(left, top, right, bottom);
// 开始绘制当前的列表项下方的分隔条
mDrawable.draw(c);
}
}
}
- 继承RecyclerView.Adapter
package com.example.materialdesign.recyclerview;
import java.util.List;
import java.util.Random;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.materialdesign.R;
import com.example.materialdesign.recyclerview.SampleRecyclerAdapter.MyViewHolder;
import com.example.materialdesign.util.DataCreateFactory;
public class SampleRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {
private final List<String> dataList = DataCreateFactory.getData(20);
@Override
// 用于创建控件
public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
// 这里 主要创建一个TextView用于显示数据
View item = LayoutInflater.from(arg0.getContext()).inflate(R.layout.recyclerview_item, arg0, false);
return new MyViewHolder(item);
}
@Override
public int getItemCount() {
return dataList.size();
}
@Override
public void onBindViewHolder(MyViewHolder arg0, int arg1) {
// 获取当前Item中显示的数据
String dataStr = dataList.get(arg1);
// 设置要显示的数据
arg0.textView.setText(dataStr.toString());
arg0.textView.setTag(dataStr);
}
/**
* 删除数据
*
* @param pos
*/
public void removeItem(int pos) {
dataList.remove(pos);
// 通知RecyclerView控件某个Item已经被删除,主要是为了动画效果
notifyItemRemoved(pos);
}
/**
* 在指定位置添加一项
*
* @param posToAdd
*/
public void addItem(int posToAdd) {
dataList.add(posToAdd, "新的列表项<" + new Random().nextInt(10000) + ">");
// 通知RecyclerView控件插入某个Item,会引起上述两个重写方法调用各自调用一次
notifyItemInserted(posToAdd);
}
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public MyViewHolder(View arg0) {
super(arg0);
textView = (TextView) arg0.findViewById(R.id.recycleItemText);
}
}
}
- 创建控件,实现布局
package com.example.materialdesign;
import android.app.Activity;
import android.graphics.Outline;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ItemDecoration;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewOutlineProvider;
import com.example.materialdesign.recyclerview.SampleDriver;
import com.example.materialdesign.recyclerview.SampleRecyclerAdapter;
//动态的添加,删除ReclerView里显示的数据
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recyclerview_main);
// 创建右下角圆形按钮,动态的裁剪图形
ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
// 获取按钮的尺寸
int fabSize = getResources().getDimensionPixelSize(R.dimen.fab_size);
// 设置轮廓的尺寸
outline.setOval(-4, -4, fabSize + 4, fabSize + 4);
}
};
View addView = findViewById(R.id.recyclerViewAdd);
addView.setOutlineProvider(viewOutlineProvider);
// 获取RecyclerView对象
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerViewList);
// 使用线性布局管理器,默认是垂直方向
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// 为RecyclerView指定布局管理器对象
recyclerView.setLayoutManager(layoutManager);
// 为RecyclerView指定分割线
ItemDecoration itemDecoration = new SampleDriver(this);
recyclerView.addItemDecoration(itemDecoration);
// 为RecyclerView指定适配器
final SampleRecyclerAdapter recyclerAdapter = new SampleRecyclerAdapter();
recyclerView.setAdapter(recyclerAdapter);
// 处理点击事件
addView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 获取第一个可视的Item的位置
int posToAdd = layoutManager.findFirstCompletelyVisibleItemPosition();
recyclerAdapter.addItem(posToAdd);
}
});
findViewById(R.id.recyclerViewDelete).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 获取第一个可视的Item的位置
int posToRemove = layoutManager.findFirstCompletelyVisibleItemPosition();
recyclerAdapter.removeItem(posToRemove);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
最终运行效果
运行起来的效果
点击右下角Button的效果
点击顶部删除按钮的效果
总结
不涉及的复杂的用法,以及上述RecyclerView是一个很标准的ListView,所以使用起来比较简单。目的主要是在能够入门该控件,以后学习到复杂的用法时候,会再来分享用法。
在启动程序时候,还遇到一个问题,大致的错误就是Error inflating class android.support.v7.widget.RecyclerViewCaused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/util/Pools$SimplePool;解决方法是,用\extras\android\support\v4\目录下的android-support-v4.jar替换项目中的v4包。
这里有篇博客关于RecyclerView详细的阐述,有兴趣的可以学习关注一下:
http://blog.csdn.net/lmj623565791/article/details/45059587