編輯:關於Android編程
參考:https://developer.android.com/training/material/lists-cards.html
1、簡介
RecyclerView已經出現了很長一段時間了,伴隨著Material Design也就是Android L的出現而出現,它的靈活性比ListView更好。和ListView一樣:它也是一個用於顯示龐大數據集的容器,可通過保持有限數量的視圖進行非常有效的滾動操作。
那麼既然有了ListView,為啥還需要RecyclerView呢?
首先看一下RecyclerView的結構:

整體上看RecyclerView的結構,其提供了拔插式的體驗,高度的解耦,異常的靈活。
RecyclerView通過提供以下功能簡化龐大數據集的顯示和處理:
1、通過布局管理器LayoutManager控制其顯示方式。
2、通過ItemDecoration控制Item間的間隔。
3、通過ItemAnimator控制Item增刪的動畫。
4、當然,點擊事件需要自己手動處理。
2、基本使用
(1)RecyclerView的使用主要分為以下幾步:
/**
* init the RecyclerViews
*/
private void initRecyclerViews() {
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// 用於提升性能
mRecyclerView.setHasFixedSize(true);
// 設置布局
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//設置適配器
List myDataset = new ArrayList();
for (int i = 0; i < 100; i++) {
myDataset.add("data" + i);
}
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
//設置Item增加、移除動畫
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
1、設置布局管理器。目前SDK中自帶三種LayoutManager,分別是:LinearLayoutManager、GridLayoutManager、
StaggeredGridLayoutManager,其中StaggeredGridLayoutManager可以實現瀑布流的效果。
也就是說:使用一個RecyclerView就可以實現ListView、GridView的效果,是不是很方便!
2、設置適配器。這個適配器需要繼承自RecyclerView.Adapter,如下所示。在MyAdapter裡面有一個內部類ViewHolder,這個類繼承自RecyclerView.ViewHolder,相當於RecyclerView規范了ViewHolder的寫法。然後在onCreateViewHolder裡面返回自定義的ViewHolder。在onBindViewHolder方法裡面設置ViewHolder裡面的控件的相關屬性。
public class MyAdapter extends RecyclerView.Adapter3、設置Item增加、移除動畫,這個是可以自定義的。{ private List mDataset; // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder public static class ViewHolder extends RecyclerView.ViewHolder { // each data item is just a string in this case public TextView mTextView; public ViewHolder(View v) { super(v); mTextView = (TextView) v.findViewById(R.id.tv_item); } } // Provide a suitable constructor (depends on the kind of dataset) public MyAdapter(List myDataset) { mDataset = myDataset; } // Create new views (invoked by the layout manager) @Override public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.activity_list_item, parent, false); // set the view's size, margins, paddings and layout parameters ViewHolder vh = new ViewHolder(v); return vh; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder holder, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element holder.mTextView.setText(mDataset.get(position)); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.size(); } }
4、設置Item間的分割線,這個也是可以自定義的。
(2)MainActivity布局:
(3)RecyclerView的Item的布局:
package com.easyliu.recyclerviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
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.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerViews();
}
/**
* init the RecyclerViews
*/
private void initRecyclerViews() {
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// 用於提升性能
mRecyclerView.setHasFixedSize(true);
// 設置布局
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//設置適配器
List myDataset = new ArrayList();
for (int i = 0; i < 100; i++) {
myDataset.add("data" + i);
}
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
//設置Item增加、移除動畫
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
}
效果如下:

以上就是RecyclerView的基本使用過程,使用的是LinearLayoutManager。
3、高級使用
(1)給Item添加點擊事件
我們發現為RecyclerView的每一項添加點擊事件並沒有ListView那麼容易,像ListView直接添加個onItemClickListener即可。這時候,接口就派上用場了!
1、定義一個接口:
public interface IOnListItemClickListener {
public void onClick(int position);
public void onLongClick(int position);
}
2、在自定義的Adapter當中添加設置接口的方法:
private IOnListItemClickListener mIOnListItemClickListener;
public void setOnListItemClickListener(IOnListItemClickListener iOnListItemClickListener) {
this.mIOnListItemClickListener = iOnListItemClickListener;
}
3、在OnBindViewHolder方法當中給當前的View設置監聽:
//設置監聽
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mIOnListItemClickListener!=null){
mIOnListItemClickListener.onClick(position);
}
}
});
holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if (mIOnListItemClickListener!=null){
mIOnListItemClickListener.onLongClick(position);
return true;
}
return false;
}
});
當然,需要注意的是,這裡的ViewHolder改了,改成了如下所示,也就是把傳進去的View保存了起來,然後在上面的方法當中獲取。
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public View mView;
public ViewHolder(View v) {
super(v);
mView=v;
mTextView = (TextView) v.findViewById(R.id.tv_item);
}
}
4、在MainActivity當中實現這個接口:
mAdapter.setOnListItemClickListener(new IOnListItemClickListener() {
@Override
public void onClick(int position) {
Snackbar.make(getWindow().getDecorView(), "onClick" + position, Snackbar.LENGTH_SHORT).show();
}
@Override
public void onLongClick(int position) {
Snackbar.make(getWindow().getDecorView(), "onLongClick" + position, Snackbar.LENGTH_SHORT).show();
}
});
以上就是給RecyclerView的item添加點擊事件的基本過程。
(2)添加和刪除數據:
1、在自定義的Adapter當中添加如下兩個方法,主要是調用了RecyclerView的notifyItemInserted和notifyItemRemoved這兩個方法。
/**
* 添加數據
* @param position
*/
public void addData(int position,String data) {
mDataset.add(position,data);
notifyItemInserted(position);
}
/**
* 刪除數據
* @param position
*/
public void removeData(int position) {
mDataset.remove(position);
notifyItemRemoved(position);
}
給Toolbar添加兩個菜單:add和delete,然後在onOptionsItemSelected方法當中根據ID執行相應的操作:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.list_add:
mAdapter.addData(1, "add");
return true;
case R.id.list_delete:
mAdapter.removeData(1);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
記住,需要給RecyclerView設置動畫,不然沒有動畫效果。
效果如下:

以上只是講了RecyclerView的基本使用方法,其深入的知識還包括:
1、LayoutManager的使用和自定義
2、ItemDecoration的使用和自定義
3、ItemAnimator的使用和自定義
下次再講~~~~
代碼下載地址:https://github.com/EasyLiu-Ly/MaterialDesignDemos
Android開發之玩轉FlexboxLayout布局
按照大神的思路寫出了一個流式布局,所有的東西都是難者不會會者不難,當自己能自定義流式布局的時候就會覺得這東西原來很簡單了。如果各位小伙伴也看過那篇文章的話,應該知道自定義
android源碼解析之(十三)--)apk安裝流程
上一篇文章中給大家分析了一下android系統啟動之後調用PackageManagerService服務並解析系統特定目錄,解析apk文件並安裝的過程,這個安裝過期實際上
Android開發基於ViewPager+GridView實現仿大眾點評橫向滑動功能
先給大家展示下效果圖,如果大家大家感覺不錯,請參考實現思路及代碼1 ViewPager類提供了多界面切換的新效果。新效果有如下特征:[1] 當前顯示一組界面中的其中一個界
Android Drawable - Shape Drawable使用詳解(附圖)
shape_rectangle.xml shape_oval.xml shape_line.xml