編輯:關於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); //設置適配器 List1、設置布局管理器。目前SDK中自帶三種LayoutManager,分別是:LinearLayoutManager、GridLayoutManager、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()); }
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系統啟動之後調用PackageManagerService服務並解析系統特定目錄,解析apk文件並安裝的過程,這個安裝過期實際上
先給大家展示下效果圖,如果大家大家感覺不錯,請參考實現思路及代碼1 ViewPager類提供了多界面切換的新效果。新效果有如下特征:[1] 當前顯示一組界面中的其中一個界
shape_rectangle.xml shape_oval.xml shape_line.xml