RecyclerView可以看作是ListView的進化版本,當然RecyclerView并不是繼承ListView的,RecyclerView直接繼承于ViewGroup父類扮叨。RecyclerView的靈活性與可替代性比listview更好,我們可以很方便的使用它完成ListView比較難完成的效果景东。
現在闻察,我們開始學習如何使用它:
** 添加依賴**
compile 'com.android.support:recyclerview-v7:21.0.+'
在xml中配置
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
** Acitvity中使用**
RecyclerView mRecyclerView;
RecyclerViewAdapter mAdapter;
LinearLayoutManager mLayoutManager;
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mLayoutManager = new LinearLayoutManager(this);
//改變方向
//mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(mLayoutManager);
//添加間隔行,若不添加該句注釋即可 RecycleViewDivider為RecyclerView.ItemDecoration的實現類
mRecyclerView.addItemDecoration(new RecycleViewDivider(this, LinearLayoutManager.HORIZONTAL));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter = new RecyclerViewAdapter(mdatas);
mRecyclerView.setAdapter(mAdapter);
可以看到守伸,RecyclerView并不像ListView那樣只要設個adpter就完成了绎秒,它有很多自己可自定義的功能,可以很方便的完成很多效果尼摹。
比如: mRecyclerView.setLayoutManager(mLayoutManager); 就給了程序員很大的發(fā)揮空間见芹,因為有了布局管理,我們可以很方便的設置為
LinearLayoutManager 線性布局同時支持橫向蠢涝、縱向
GridLayoutManager時 為網格布局管理器
StaggeredGridLayoutManager 瀑布式布局管理器
- 適配器編寫
RecycleView是對ListView以及GridView的升級玄呛,在使用的時候同源更新需要使用Adapter適配器。但是RecycleView使用的適配器并不是之前的BaseAdapter了和二。RecycleView使用的適配器需要繼承RecyclerView.Adapter<VH extends RecycleView.ViewHolder>
我們將適配器的編寫流程分為:
1.繼承 RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>
2.完成內部類 ViewHolder 這個 ViewHolder不再是以前的BaseAdapter時我們寫的ViewHolder把鉴,而是需要繼承RecyclerView.ViewHolder抽象類的ViewHolder
3.編寫構造方法
4.onBindViewHolder中進行每個item的操作
5.若需要監(jiān)聽點擊事件,我們需要定義回調接口儿咱,并在第四步進行item的view操作時庭砍,添加監(jiān)聽事件回掉該接口
以下便是我的RecyclerViewAdapter代碼
/**
* Created by Xiamin on 2016/9/2.
*/
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
ListView
private List<String> mdata;
public RecyclerViewAdapter(List<String> data) {
mdata = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.textView.setText(mdata.get(position));
/**
* 在綁定viewholder時 給每個view設置上觸摸監(jiān)聽
*/
if (mOnItemClickListener != null) {
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnItemClickListener.onItemClick(holder.itemView, position);
}
});
holder.textView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
mOnItemClickListener.onItemLongClick(holder.itemView, position);
//返回true 這樣觸發(fā)了onLongClick后便不會再觸發(fā)onClick了
return true;
}
});
}
}
@Override
public int getItemCount() {
return mdata.size();
}
/**
* 定義接口用于短按長按的回調
*/
public interface OnRecyclerViewItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
/**
* 添加點擊事件
*/
private OnRecyclerViewItemClickListener mOnItemClickListener = null;
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
this.mOnItemClickListener = listener;
}
public void addData(int position) {
mdata.add(position, "Insert One");
notifyItemInserted(position);
}
public void removeData(int position) {
mdata.remove(position);
notifyItemRemoved(position);
/**
* 非常重要!;觳骸怠缸! 若不使用該方法通知適配器數據已經變了,notifyItemRemoved會導致item下標錯亂
* 因為刪除某一項時調用notifyItemRemoved后钳宪,顯示的item是不會調用onBind方法的揭北,
* 所以position并沒有被刷新。這時候得到的position值就是錯誤的吏颖。
*/
notifyItemRangeChanged(position, mdata.size());
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
}
}
初步運行
發(fā)現可以運行搔体,類似于簡單的listview(當然,item的xml配置代碼被我省略了)
- 添加監(jiān)聽事件
我選擇在長按item時刪除該item半醉,刪除動畫在由該行設置
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter.setOnItemClickListener(new RecyclerViewAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this, position + "pressed", LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, int position) {
Toast.makeText(MainActivity.this, position + "Longpressed", LENGTH_SHORT).show();
mAdapter.removeData(position);
}
});
** 遇坑**
完成該功能后疚俱,測試發(fā)現,刪除會出現問題缩多,動畫是有了呆奕,但是下標會亂养晋,導致刪除錯誤item、
因此便有了該行代碼梁钾。
因為刪除某一項時調用notifyItemRemoved后绳泉,顯示的item是不會調用onBind方法的,所以position并沒有被刷新姆泻。這時候得到的position值就是錯誤的零酪。我們需要手動使adapter給后面的item重新onBind
notifyItemRangeChanged(position, mdata.size());
至此,RecyclerView的便正常工作了拇勃。
總結
本文只是RecyclerView的一些基本使用四苇,有很多強大的功能還未能接觸,本文也比較初步潜秋,僅作入門引導蛔琅。