Google在推出Android5.0的時候推出了Material Design ,而RecyclerView是Material Design 重要元件之一。當然還有CardView/Palette。
RecyclerView是用來替換傳統的ListView和GridView,瀑布流效果的。是的RecyclerView這一個控件,可以實作這三個效果。雖然在開始使用recyclerview的時候會感到有些男,但是用熟練了會發現recyclerview十分強大。它可以給每一item裡面的控件設定點選時間,而不需要擔心事件沖突的問題,如果是使用listview或者是gridview就必須要解決事件沖突,甚至listview或gridview的item隻能設定一個點選事件,否則就會造成事件沖突,而這些沖突并不好解決。是以recyclerview來了。
首先在項目中內建RecyclerView,在build.gradle添加RecyclerView的依賴
這樣項目中就內建 recyclerview了,Android Studio 會自動聯網下載下傳 recyclerview包。
在activity_main.xml中,使用recyclerview.
<code><</code><code>android.support.v7.widget.RecyclerView</code>
<code> </code><code>android:id</code><code>=</code><code>"@+id/recyclerView"</code>
<code> </code><code>android:layout_width</code><code>=</code><code>"match_parent"</code>
<code> </code><code>android:layout_height</code><code>=</code><code>"match_parent"</code> <code>/></code>
布局中已經有了recyclerview的控件,下面就開始在代碼中編寫。
在這裡解釋一下recyclerview的使用。就像listview那樣,recyclerview也需要一個擴充卡;在我們優化listview的時候,我們經常會使用到一個内部類ViewHolder來儲存item中的控件,以便于item的複用。而現在recyclerview則必須使用ViewHolder。這個ViewHolder必須繼承RecyclerView.ViewHolder,RecyclerView.ViewHolder有一個參數的構造方法,傳入的是一個view,這個view 就是recyclerview的item。
RecyclerViewHolder:
<code>public</code> <code>class</code> <code>RecyclerViewHolder </code><code>extends</code> <code>RecyclerView.ViewHolder {</code>
<code> </code><code>public</code> <code>TextView textView;</code>
<code> </code><code>public</code> <code>ImageView imageView;</code>
<code> </code><code>public</code> <code>RecyclerViewHolder(View itemView) {</code>
<code> </code><code>super</code><code>(itemView);</code>
<code> </code><code>textView = (TextView) itemView.findViewById(R.id.textView);</code>
<code> </code><code>imageView = (ImageView) itemView.findViewById(R.id.imageView);</code>
<code> </code><code>}</code>
<code>}</code>
RecyclerViewHolder寫好之後就開始寫Adapter.同樣RecyclerAdapter需要繼承RecyclerView.Adapter<RecyclerViewHolder>,泛型ViewHolder就是自己自定義的RecyclerViewHolder。Adapter的寫法如下:
<code>public</code> <code>class</code> <code>RecyclerAdapter </code><code>extends</code> <code>RecyclerView.Adapter<RecyclerViewHolder> {</code>
<code> </code><code>private</code> <code>List<Map<String, String>> dataList;</code>
<code> </code><code>public</code> <code>RecyclerAdapter() {</code>
<code> </code><code>dataList = </code><code>new</code> <code>ArrayList<>();</code>
<code> </code><code>public</code> <code>void</code> <code>addAll(List<Map<String, String>> data){</code>
<code> </code><code>dataList.addAll(data);</code>
<code> </code><code>/**</code>
<code> </code><code>*</code>
<code> </code><code>* @param viewType 對應的是getItemViewType(int position)方法傳回的數值</code>
<code> </code><code>*/</code>
<code> </code><code>@Override</code>
<code> </code><code>public</code> <code>RecyclerViewHolder onCreateViewHolder(ViewGroup parent, </code><code>int</code> <code>viewType) {</code>
<code> </code><code>View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, </code><code>false</code><code>);</code>
<code> </code><code>return</code> <code>new</code> <code>RecyclerViewHolder(view);</code>
<code> </code><code>* @param holder 對應的是onCreateViewHolder方法,傳回的RecyclerViewHolder</code>
<code> </code><code>* @param position 目前的item的位置</code>
<code> </code><code>public</code> <code>void</code> <code>onBindViewHolder(RecyclerViewHolder holder, </code><code>int</code> <code>position) {</code>
<code> </code><code>holder.textView.setText(dataList.get(position).get(</code><code>"data"</code><code>));</code>
<code> </code><code>public</code> <code>int</code> <code>getItemCount() {</code>
<code> </code><code>return</code> <code>dataList.size();</code>
MainActivity中的代碼。
<code>public</code> <code>class</code> <code>MainActivity </code><code>extends</code> <code>AppCompatActivity {</code>
<code> </code><code>private</code> <code>RecyclerView recyclerView;</code>
<code> </code><code>//使用線性布局管理器,設定的方向orientation是預設,即垂直方向</code>
<code> </code><code>private</code> <code>LinearLayoutManager manager;</code>
<code> </code><code>//擴充卡</code>
<code> </code><code>private</code> <code>RecyclerAdapter adapter;</code>
<code> </code><code>//資料源</code>
<code> </code><code>private</code> <code>List<Map<String, String>> list;</code>
<code> </code><code>protected</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>
<code> </code><code>super</code><code>.onCreate(savedInstanceState);</code>
<code> </code><code>setContentView(R.layout.activity_main);</code>
<code> </code><code>recyclerView = (RecyclerView) findViewById(R.id.recyclerView);</code>
<code> </code><code>manager = </code><code>new</code> <code>LinearLayoutManager(</code><code>this</code><code>);</code>
<code> </code><code>adapter = </code><code>new</code> <code>RecyclerAdapter();</code>
<code> </code><code>//設定布局管理器</code>
<code> </code><code>recyclerView.setLayoutManager(manager);</code>
<code> </code><code>//給recyclerview設定擴充卡</code>
<code> </code><code>recyclerView.setAdapter(adapter);</code>
<code> </code><code>list = </code><code>new</code> <code>ArrayList<>();</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i=</code><code>0</code><code>;i<</code><code>50</code><code>;i++)</code>
<code> </code><code>{</code>
<code> </code><code>Map<String,String> map = </code><code>new</code> <code>HashMap<>();</code>
<code> </code><code>map.put(</code><code>"data"</code><code>, </code><code>"item--> "</code><code>+i);</code>
<code> </code><code>list.add(map);</code>
<code> </code><code>}</code>
<code> </code><code>adapter.addAll(list);</code>
<code> </code><code>adapter.notifyDataSetChanged();</code>
recyclerview實作listview的效果就完成了,運作效果:
<a href="http://s3.51cto.com/wyfs02/M00/7D/CB/wKiom1bwAm6gFtn-AACorefEJoQ425.png" target="_blank"></a>
如果是想每個item橫向滑動的話,隻需要使用LinearLayoutManager的三個參數的構造方法就行了,new LInearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true)就可以實作橫向滑動的效果了。
recyclerView實作GridView的效果。需要是用是GridLayoutManager。将recyclerView的布局管理器更換成GridLayoutManager manager = new GridLayoutManager(this, 2),效果圖如下:
<a href="http://s5.51cto.com/wyfs02/M02/7D/CB/wKiom1bwBiXzf2LxAADEl4akjZo408.png" target="_blank"></a>
給RecyclerView添加滾動監聽。與listView和gridView有寫不同,recyclerView判斷滾動到哪一個位置的餓時候,需要使用到使用到布局管理器(前面設定的recyclerview.setLayoutManager())。滾動監聽的方法有兩個,setOnScrollListener(已不推薦使用)和addOnScrollListener。兩個方法本質上是一緻的。代碼如下:
<code>recyclerView_follow.addOnScrollListener(</code><code>new</code> <code>RecyclerView.OnScrollListener() {</code>
<code> </code><code>public</code> <code>void</code> <code>onScrollStateChanged(RecyclerView recyclerView, </code><code>int</code> <code>newState) {</code>
<code> </code><code>super</code><code>.onScrollStateChanged(recyclerView, newState);</code>
<code> </code><code>//滾動的狀态改變時,調用此方法。</code>
<code> </code><code>public</code> <code>void</code> <code>onScrolled(RecyclerView recyclerView, </code><code>int</code> <code>dx, </code><code>int</code> <code>dy) {</code>
<code> </code><code>super</code><code>.onScrolled(recyclerView, dx, dy);</code>
<code> </code><code>//螢幕中最下面一個item的所在資料源的位置(postion)。</code>
<code> </code><code>int</code> <code>lastVisiableItem = manager.findLastVisibleItemPosition();</code>
<code> </code><code>//一共有多少個</code>
<code> </code><code>int</code> <code>totalItemCount = manager.getItemCount();</code>
<code> </code><code>//當滑動到倒數第二個item時,即聯網擷取下一頁的資料</code>
<code> </code><code>if</code> <code>(lastVisiableItem >= totalItemCount - </code><code>2</code> <code>&& dy > </code><code>0</code><code>) {</code>
<code> </code><code>page++;</code><code>//第二頁</code>
<code> </code><code>reloadData(page);</code>
<code>});</code>
給RecyclerView添加監聽事件:
首先在Adapter中的onBindViewHolder方法中設定點選事件,使用holder.xxx.setOnClickListener()設定點選事件.RecyclerView避免了事件的沖突問題,可以給每個item中的控件設定點選事件.
本文轉自 墨宇hz 51CTO部落格,原文連結:http://blog.51cto.com/zzhhz/1753676