在Listview中使用了好久的viewholder、setTag、getTag來實現Item複用後, Google大大終於看不下去了。推出了明日之星RecyclerView,現已加入support.v7豪華套餐。顧名思義,RecyclerView自己是無論怎麼佈局的。它自己只負責,加載看得見的viewHolder,釋放看不見的viewHolder。這一功能就代替掉了,ListView中麻煩的Item複用設計。而對於佈局的控制,RecyclerView則依賴於LayoutManager。下面,我用一個簡單的demo,記錄下RecyclerView的用法。java
1、如何加入support.v7包(Android Studio中)。android
方法1:右鍵項目->Open Module Settings->Dependencies->綠色加號->Library dependency -> recyclerview-v7->OKapp
方法2:dom
dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:appcompat-v7:22.1.1' compile 'com.android.support:recyclerview-v7:22.1.1' }
in build.gradleide
2、我自定義了MyRecyclerView繼承RecyclerView,這不是必需的,我只是爲了方便之後擴展。佈局
3、完成佈局文件中 activity_main.xmlgradle
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <fallflowscrollviewdemo.com.dream.fishbonelsy.recyclerdemo.MyRecyclerView android:id="@+id/recycler_view_id" android:layout_width="match_parent" android:layout_height="match_parent"> </fallflowscrollviewdemo.com.dream.fishbonelsy.recyclerdemo.MyRecyclerView> </RelativeLayout>
4、完成Item的佈局 normal_item_layout.xmlui
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/normal_item_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_marginTop="5dp" android:background="#44ff0000" android:gravity="center" android:textSize="30sp" /> </LinearLayout>
5、完成Item的ViewHolder,並給予子控件實例。 MyRecyclerViewHold.javathis
import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.TextView; /** * Created by fishboneLsy on 2015/7/2. */ public class MyRecyclerViewHold<E extends Object> extends RecyclerView.ViewHolder { private TextView textView; public MyRecyclerViewHold(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.normal_item_id); } public void setItemContent(E data){ textView.setText(data.toString()); } }
6、實現RecyclerView的適配器RecyclerViewAdapter。 MyRecyclerViewAdapter.javaspa
import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.List; /** * Created by fishboneLsy on 2015/7/2. */ public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewHold> { private Context mContext; private List<?> mDataList; private int mNormalItemLayout;
/**
* MyRecyclerViewAdapter Construct
* @param context
* @param dataList
* @param layoutId ItemLayoutId
*/
public MyRecyclerViewAdapter(Context context, List<?> dataList, int layoutId) { mContext = context; mDataList = dataList; mNormalItemLayout = layoutId; } @Override public int getItemViewType(int position) { return super.getItemViewType(position); } @Override public MyRecyclerViewHold onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(mNormalItemLayout, parent, false); MyRecyclerViewHold viewHold = new MyRecyclerViewHold(view); return viewHold; } @Override public void onBindViewHolder(MyRecyclerViewHold holder, int position) { try { holder.setItemContent(mDataList.get(position)); }catch (Exception e){ e.printStackTrace(); } } @Override public int getItemCount() { if (mDataList != null && mDataList.size() > 0) { return mDataList.size(); } return 0; } }
adapter中包含了四個方法,它們分別是:
一、public int getItemViewType(int position) 獲取Item的類型,默認是0。
二、public MyRecyclerViewHold onCreateViewHolder(ViewGroup parent, int viewType) 生成Item的ViewHolder
三、public void onBindViewHolder(MyRecyclerViewHold holder, int position)將Item的ViewHolder與數據List鏈接
四、public int getItemCount()獲取Item總數
7、在Activity中建立RecyclerView並配置參數、輸入數據。
import android.app.Activity; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.Menu; import android.view.MenuItem; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private MyRecyclerView recyclerView; private MyRecyclerViewAdapter adapter; private List<String> mDataList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (MyRecyclerView) findViewById(R.id.recycler_view_id); /* create LayoutManager */ RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); mDataList = new ArrayList<String>(); adapter = new MyRecyclerViewAdapter(this , mDataList , R.layout.normal_item_layout); recyclerView.setAdapter(adapter); // create data for test for (int i = 0 ; i < 40 ; i++){ StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("test:").append(i); for (int j = 0 ; j < (int)(Math.random()*10) ; j++){ stringBuilder.append("\n"+j); } mDataList.add(stringBuilder.toString()); } adapter.notifyDataSetChanged(); } }
其中,LayoutManager決定了RecyclerView的佈局方式。能夠經過更換LayoutManager來改變RecyclerView的佈局方式。
按照上面的代碼,呈現的效果以下:
咱們能夠將:
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
改成:
RecyclerView.LayoutManager layoutManager = new StaggeredGridLayoutManager(4 , StaggeredGridLayoutManager.VERTICAL);
就能夠輕鬆地完成4列瀑布流效果:
至此,RecyclerView的簡單使用算是完成。可是RecyclerView也有一些缺點。好比,它沒有headerView。這在一些須要頭部的地方會顯得很不方便。因此我在一開始就用了自定義的MyRecyclerView來繼承RecyclerView爲後面的擴展留了空間。
Done!