過去的這一兩年, RecyclerView越來越引起了我們Android開發(fā)人員的注意,RecyclerView的靈活性還有性能上有很大的提升。
想必大家或多或少的接觸過或者了解過RecyclerView,為什么沒有用起來,原因大概如下?
- 大家對于ListView的熟悉、,ListView基本可以滿足應用的大部分場景,為什么要換RecyclerView?
- ListView穩(wěn)定,有很多相關開源庫,特別的好用。
- RecyclerView不能添加頭布局,而ListView可以。
RecyclerView有什么優(yōu)缺點?如何使用RecyclerView和解決這些問題?
RecyclerView 的使用和優(yōu)點
-
布局效果
RecyclerView最大的優(yōu)勢就是靈活,RecyclerView 同時支持 線性布局、網(wǎng)格布局、瀑布流布局三種,而且還能夠控制橫向還是縱向滾動。
RecyclerView.LayoutManager,這是一個抽象類,系統(tǒng)提供了3個實現(xiàn)類:
- LinearLayoutManager 線性管理器,支持橫向、縱向。
- GridLayoutManager 網(wǎng)格布局管理器
- StaggeredGridLayoutManager 瀑布就式布局管理器
注意:在實例化RecyclerView之后,我們需要使用setLayoutManager()給它設置布局管理器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); // 創(chuàng)建線性布局管理器
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); // 設置線性布局為橫向(默認為縱向)
mRecyclerView.setLayoutManager(linearLayoutManager); // 設置布局管理器
-
自帶ViewHolder
RecyclerView.Adapter,比BaseAdapter做了更好的封裝,強制需要創(chuàng)建ViewHolder,這樣的好處就是避免了初學者寫性能不佳的代碼
繼承重寫 RecyclerView.Adapter 和 RecyclerView.ViewHolder
// 第一步:繼承重寫 RecyclerView.Adapter 和 RecyclerView.ViewHolder
public class AuthorRecyclerAdapter extends RecyclerView.Adapter<AuthorRecyclerAdapter.AuthorViewHolder> {
@Override
public AuthorViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return viewHolder;
}
@Override
public void onBindViewHolder(AuthorViewHolder holder, int position) {
}
@Override
public int getItemCount() {
if (list == null) {
return 0;
}
return list.size();
}
class AuthorViewHolder extends RecyclerView.ViewHolder {
public AuthorViewHolder(View itemView) {
super(itemView);
}
}
}
-
控制item的間隔分割線,
可以使用addItemDecoration(ItemDecoration decor),不過里邊的ItemDecoration是一個抽象類,需要自己去實現(xiàn)
-
實現(xiàn)增刪動畫
通過setItemAnimator(ItemAnimator animator)可以實現(xiàn)增刪動畫
RecyclerView自帶添加、刪除動畫,而ListView則需添加額外的代碼才能實現(xiàn)。
刪除調(diào)用RecyclerView的adapter的notifyItemRemoved
添加調(diào)用RecyclerView的adapter的notifyItemInserted
說到adapter我們就來說說RecyclerView.Adapter和BaseAdapter相比,額外提供了一下這些方法:
// 數(shù)據(jù)發(fā)生了改變,那調(diào)用這個方法,傳入改變對象的位置。
public final void notifyItemChanged(int position);
// 可以刷新從positionStart開始itemCount數(shù)量的item了
public final void notifyItemRangeChanged(int positionStart, int itemCount);
// 添加,傳入對象的位置。
public final void notifyItemInserted(int position);
// 刪除,傳入對象的位置。
public final void notifyItemRemoved(int position);
// 對象從fromPosition移動到toPosition
public final void notifyItemMoved(int fromPosition, int toPosition);
//批量添加
public final void notifyItemRangeInserted(int positionStart, int itemCount);
//批量刪除
public final void notifyItemRangeRemoved(int positionStart, int itemCount);
如何為RecyclerView添加Header和Footer
- 在MyAdapter類中,提供setHeaderView()和setFooterView()兩個方法,我們就是通過這兩個方法從Activity將headerView和footerView傳遞過來的,利用getItemViewType()返回Item的類型,根據(jù)不同的類型,我們創(chuàng)建不同的Item的View。
package com.study.wnw.recyclerviewheaderfooter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
/** * Created by wnw on 16-5-20. */
public class MyAdapter extendsRecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int TYPE_HEADER = 0; //說明是帶有Header的
public static final int TYPE_FOOTER = 1; //說明是帶有Footer的
public static final int TYPE_NORMAL = 2; //說明是不帶有header和footer的
//獲取從Activity中傳遞過來每個item的數(shù)據(jù)集合
private List<String> mDatas;
//HeaderView, FooterView
private View mHeaderView;
private View mFooterView;
//構造函數(shù)
public MyAdapter(List<String> list){
this.mDatas = list;
}
//HeaderView和FooterView的get和set函數(shù)
public View getHeaderView() {
return mHeaderView;
}
public void setHeaderView(View headerView) {
mHeaderView = headerView;
notifyItemInserted(0);
}
public View getFooterView() {
return mFooterView;
}
public void setFooterView(View footerView) {
mFooterView = footerView;
notifyItemInserted(getItemCount()-1);
}
/** 重寫這個方法,很重要,是加入Header和Footer的關鍵,我們通過判斷item的類型,從而綁定不同的view * */
@Override
public int getItemViewType(int position) {
if (mHeaderView == null && mFooterView == null){
return TYPE_NORMAL;
}
if (position == 0){
//第一個item應該加載Header
return TYPE_HEADER;
}
if (position == getItemCount()-1){
//最后一個,應該加載Footer
return TYPE_FOOTER;
}
return TYPE_NORMAL;
}
//創(chuàng)建View,如果是HeaderView或者是FooterView,直接在Holder中返回
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(mHeaderView != null && viewType == TYPE_HEADER) {
return new ListHolder(mHeaderView);
}
if(mFooterView != null && viewType == TYPE_FOOTER){
return new ListHolder(mFooterView);
}
View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ListHolder(layout);
}
//綁定View,這里是根據(jù)返回的這個position的類型,從而進行綁定的, HeaderView和FooterView, 就不同綁定了
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(getItemViewType(position) == TYPE_NORMAL){
if(holder instanceof ListHolder) {
//這里加載數(shù)據(jù)的時候要注意,是從position-1開始,因為position==0已經(jīng)被header占用了
((ListHolder) holder).tv.setText(mDatas.get(position-1));
return;
}
return;
}else if(getItemViewType(position) == TYPE_HEADER){
return;
}else{
return;
}
}
//在這里面加載ListView中的每個item的布局
class ListHolder extends RecyclerView.ViewHolder{
TextView tv;
public ListHolder(View itemView) {
super(itemView);
//如果是headerview或者是footerview,直接返回
if (itemView == mHeaderView){
return;
}
if (itemView == mFooterView){
return;
}
tv = (TextView)itemView.findViewById(R.id.item);
}
}
//返回View中Item的個數(shù),這個時候,總的個數(shù)應該是ListView中Item的個數(shù)加上HeaderView和FooterView
@Override
public int getItemCount() {
if(mHeaderView == null && mFooterView == null){
return mDatas.size();
}else if(mHeaderView == null && mFooterView != null){
return mDatas.size() + 1;
}else if (mHeaderView != null && mFooterView == null){
return mDatas.size() + 1;
}else {
return mDatas.size() + 2;
}
}
}
- 在Activity添加布局
mMyAdapter.setHeaderView(header);
mMyAdapter.setFooterView(footer);
如何給RecyclerView添加點擊事件
RecyclerView強大,好用,但是使用率很高的ItemClickListener卻沒有添加。
點擊事件的實現(xiàn),有常見的三種方法:
- 通過 RecyclerView已有的方法 addOnItemTouchListener()實現(xiàn)
- 在創(chuàng)建 ItemView時添加點擊監(jiān)聽
- 當 ItemViewattach RecyclerView時實現(xiàn)
具體參考:給RecyclerView封裝個Adapter吧(更優(yōu)雅的添加點擊事件)
更多功能介紹將持續(xù)更新中。。。。。。
參考文獻 及相關框架:
基礎篇:
擴展:
-
twoway-view 封裝了RecyclerView常用方法,如click等等,以及支持了更多不同的布局,使得RecyclerView使用起來更簡單!