Android實現RecyclerView自定義列表、點擊事件以及下拉刷新
Android使用RecyclerView
1. 什么是RecyclerView
RecyclerView 是 Android-support-v7-21 版本中新增的一個 Widgets,官方對于它的介紹則是:RecyclerView 是 ListView 的升級版本,更加先進和靈活。
簡單來說就是:RecyclerView是一種新的視圖組,目標是為任何基于適配器的視圖提供相似的渲染方式。它被作為ListView和GridView控件的繼承者,在最新的support-V7版本中提供支持。
2. 使用RecyclerView需要掌握什么
- Adapter — 包裝數據集合并且為每個條目創建視圖
- LayoutManager — 將每個條目的視圖放置于適當的位置
- OnItemClickListener — 給每個條目設置點擊事件
- SwipeRefreshLayout — 給RecyclerView添加下拉刷新事件
- ItemAnimator — 在每個條目的視圖的周圍或上面繪制一些裝飾視圖
- ItemDecoration — 在條目被添加、移除或者重排序時添加動畫效果
3. 使用RecyclerView前需要準備什么
添加依賴包(以Android Studio為例)
4. 自定義Adapter
RecyclerView.Adapter包含了一種新型適配器,其實與以前我們使用的適配器基本類似,只是稍微有所不同,比如viewholder它幫我們封裝好了,不用像以前使用listview的適配器一樣自己去寫viewholder了。
Item視圖如下:
實例代碼如下:
public class RecyclerAdapter extends RecyclerView.Adapter {
private List<Model> models;
public RecyclerAdapter(List<Model> models){
this.models = models;
}
class ViewHolder extends RecyclerView.ViewHolder{
private ImageView picture;
private TextView title,text;
public ViewHolder(View itemView) {
super(itemView);
picture = (ImageView) itemView.findViewById(R.id.picture);
title = (TextView) itemView.findViewById(R.id.title);
text = (TextView) itemView.findViewById(R.id.text);
}
public ImageView getPicture(){
return picture;
}
public TextView getTitle(){
return title;
}
public TextView getText(){
return text;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view,null));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final ViewHolder vh = (ViewHolder) holder;
vh.getPicture().setImageResource(models.get(position).getPicture());
vh.getTitle().setText(models.get(position).getTitle());
vh.getText().setText(models.get(position).getText());
}
@Override
public int getItemCount() {
return models.size();
}
}</code></pre>
5. LayoutManager有什么作用
由于RecyclerView已經不單單像以前ListView或者GridView一樣,它被作為ListView和GridView控件的繼承者,所以在使用它的時候需要通過設置它的LayoutManager去規定它是哪一種類型,另外也可通過設置LayoutManager去設置它是橫向還是縱向的列表,以及是否反轉。
縱向列表:(第三個參數是設置是否反轉,即滑動方向)
mLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
recyclerview.setLayoutManager(mLayoutManager);

橫向列表:
mLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
recyclerview.setLayoutManager(mLayoutManager);

垂直表格布局:
mLayoutManager = new GridLayoutManager(this,2);
recyclerview.setLayoutManager(mLayoutManager);
水平表格布局:(第四個參數代表是否反轉)
mLayoutManager = new GridLayoutManager(this,2,LinearLayoutManager.HORIZONTAL,false);
recyclerview.setLayoutManager(mLayoutManager);

6. 為什么要自己添加OnItemClickListener
RecyclerView有一個缺點,在RecyclerView中,沒有一個onItemClickListener方法。所以目前在適配器中處理這樣的事件比較好。如果想要從適配器上添加或移除條目,需要明確通知適配器。這與先前的notifyDataSetChanged()方法稍微有些不同。具體操作在適配器代碼中就可以體現。
具體代碼如下:
public class RecyclerAdapter extends RecyclerView.Adapter {
private List<Model> models;
public RecyclerAdapter(List<Model> models){
this.models = models;
}
class ViewHolder extends RecyclerView.ViewHolder{
private ImageView picture;
private TextView title,text;
public ViewHolder(View itemView) {
super(itemView);
picture = (ImageView) itemView.findViewById(R.id.picture);
title = (TextView) itemView.findViewById(R.id.title);
text = (TextView) itemView.findViewById(R.id.text);
}
public ImageView getPicture(){
return picture;
}
public TextView getTitle(){
return title;
}
public TextView getText(){
return text;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view,null));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final ViewHolder vh = (ViewHolder) holder;
vh.getPicture().setImageResource(models.get(position).getPicture());
vh.getTitle().setText(models.get(position).getTitle());
vh.getText().setText(models.get(position).getText());
//如果設置了回調,就設置點擊事件
if (mOnItemClickListener != null){
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(vh.itemView,position);
}
});
}
}
@Override
public int getItemCount() {
return models.size();
}
/** * ItemClick的回調接口 */
public interface OnItemClickListener{
void onItemClick(View view,int position);
}
private OnItemClickListener mOnItemClickListener;
public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener){
this.mOnItemClickListener = mOnItemClickListener;
}
}</code></pre>
7. 實現下拉刷新與上拉加載更多
其實跟以前一樣,原生的ListView或者GridView都不能滿足實際App的需要,很多時候都要通過自定義View去實現列表的下拉刷新和上拉加載,RecyclerView也是一樣,不過這里不會介紹如何去自定義RecyclerView,相反,我們會借用SwipeRefreshLayout這個組件,更快地去實現列表刷新功能
界面布局如下:
<view
android:id="@+id/swipeRefreshLayout"
class="android.support.v4.widget.SwipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</view></code></pre>
設置下拉刷新監聽事件:
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//重新獲取數據
//獲取完成swipeRefreshLayout.setRefreshing(false);
}
});
設置上拉加載更多可以通過設置滑動監聽事件來實現:
recyclerview.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE
&& lastVisibleItem + 1 == adapter.getItemCount()) {
swipeRefreshLayout.setRefreshing(true);
//分頁獲取數據
//獲取完成swipeRefreshLayout.setRefreshing(false);
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
}
});</code></pre>
8. ItemAnimator 與ItemDecorator
由于RecyclerView里沒有自帶分割線,所以就出現了ItemDecorator,但其實還有另外一種方法,就是直接在Item界面布局中添加分割線,這樣可以省去很多代碼;
而ItemAnimator簡單來說是會根據適配器上收到的相關通知去動畫的顯示組件的修改,添加和刪除等。它會自動添加和移除item的動畫。自帶的默認效果也不錯,已經非常好了。因為這兩項不是很常用,所以這里就不多加介紹了,有興趣的同學可以上網找詳細的資料學習。
來自: http://blog.csdn.net/u014756589/article/details/51280659