您的位置:首页 > 其它

当ListView遇上RecyclerView, ListView将甘拜下风

2016-06-07 20:29 435 查看
通过本篇博客,你将学到以下知识点

①RecyclerView与ListView相比它的优点

②RecyclerView的初步用法

③RecyclerView的Adapter的用法

④给RecyclerView增加条目点击事件

1.RecyclerView是什么?

RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字recylerview即回收view也可以看出。看到这也许有人会问,不是已经有ListView了吗,为什么还要RecylerView呢?这就牵扯到第二个问题了。


2.RecyclerView的优点是什么?

根据官方的介绍RecylerView是ListView的升级版,既然如此那RecylerView必然有它的优点,现就RecylerView相对于ListView的优点罗列如下:


①RecylerView封装了viewholder的回收复用,也就是说RecylerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的 逻辑被封装了,写起来更加简单。

②提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecylerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还有StaggeredGridLayoutManager等),也就是说RecylerView不再拘泥于ListView的线性展示方式,它也可以实现GridView的效果等多种效果。你想控制Item的分隔线,可以通过继承RecylerView的ItemDecoration这个类,然后针对自己的业务需求去抒写代码。

③可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。

3.RecyclerView的用法

目前SDK中提供了三种自带的LayoutManager:

LinearLayoutManager:线性布局,横向或者纵向滑动列表
GridLayoutManager:表格布局
StaggeredGridLayoutManager:流式布局,例如瀑布流效果


效果展示:

可对item进行增加和删除。



实现步骤:

1.创建一个继承于RecyclerView.Adapter的子类作为RecyclerView的适配器
2.创建一个继承于RecyclerView.ViewHolder的子类作为当前适配器的viewholder
并将其作为RecyclerView.Adapter的泛型来使用(统一开发规范)
3.实现当前适配器中的方法
4.加载布局,并初始化MyViewHolder,然后通过onCreateViewHolder返回
5.通过onBindViewHolder方法填充控件


简单的RecyclerView使用方法:

一.添加依赖



二、编写代码

1.添加完依赖之后,就开始写代码了,与ListView用法类似,也是先在xml布局文件中创建一个RecyclerView的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>


2.创建完布局之后在MainActivity中获取这个RecyclerView,并声明LayoutManager与Adapter,代码如下:

public class GridRecyclerViewActivity extends Activity {
private RecyclerView recyclerView;

private List<String> list;

private RecyclerViewAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview2);
list = new ArrayList<String>();
adapter = new RecyclerViewAdapter(this, list);
initEvent();
//如果想要一个Grid布局的列表,只要声明LayoutManager为GridLayoutManager即可:
GridLayoutManager layoutManager = new GridLayoutManager(this, 4);
/**
* listview样式的滑动方向由setOrientation方法决定
* LinearLayout.VERTICAL:竖向滑动
* LinearLayout.HORIZONTAL:横向滑动
* GridLayoutManager构造方法中的第二个参数:
* 当setOrientation为LinearLayout.VERTICAL时,参数代表列数
* 当setOrientation为LinearLayout.HORIZONTAL,参数代表行数
*/
layoutManager.setOrientation(LinearLayout.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
loadData();
}

private void initEvent() {
adapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
//TODO 处理点击事件
list.add(position,"添加");
adapter.notifyDataSetChanged();
}

@Override
public void onItemLongClick(View view, int position) {
//TODO 处理长按事件
list.remove(position);//长按删除
// adapter.notifyDataSetChanged();
adapter.notifyItemRemoved(position);
}
});
}

private void loadData() {
for (int i = 0; i < 100; i++) {
list.add(i + "");
}
adapter.notifyDataSetChanged();
}
}


3.接下来的问题就是Adapter的创建:

①onCreateViewHolder()

这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。

②onBindViewHolder()

这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView。

③getItemCount()

这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。

public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>
{
private Context context;

private List<String> list;

private OnItemClickListener onItemClickListener;

public RecyclerViewAdapter(Context context, List<String> list)
{
this.context = context;
this.list = list;
}

//创建新View,被LayoutManager所调用
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View convertview = LayoutInflater.from(context).inflate(
R.layout.adapter_recycler_view, parent, false);
Log.i("info", "onCreateViewHolder");
return new MyViewHolder(convertview);
}

// 填充控件(同listview中的getView()方法,只作控件的赋值业务)

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position)
{
//将数据与界面进行绑定的操作
holder.tv.setText(list.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (onItemClickListener != null)
{
onItemClickListener.onItemClick(v, position);
}
Log.i("info", "itemView被点击了===>" + position);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View v)
{
if (onItemClickListener != null)
{
int pos = holder.getLayoutPosition();//TODO 该方法用于获得和更新当前的位置,防止错位
onItemClickListener.onItemLongClick(v, pos);
}
Log.i("info", "itemView被长按了===>" + position);
// 长按的返回值:当返回true表示消费掉当前事件,会使后续的操作无法获取到该事件
// 如果返回false,则可触发onClick监听
return true;
}
});
}

@Override
public int getItemCount()
{
return list.size();
}

/**
* 继承于RecyclerView.ViewHolder的作用 1.统一开发规范 2.增强封装性
*/
//自定义的ViewHolder,持有每个Item的的所有界面元素
public class MyViewHolder extends RecyclerView.ViewHolder
{
private TextView tv;

public MyViewHolder(View itemView)
{
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}

public interface OnItemClickListener
{
// 点击回调方法
void onItemClick(View view, int position);

// 长按回调方法
void onItemLongClick(View view, int position);
}

public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
this.onItemClickListener = onItemClickListener;
}
}


不懂的可以再浏览下大神的博客,博客的连接是:http://blog.csdn.net/skykingf/article/details/50827141
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: