第一部分html
RecyclerVIew是一個能夠替代listview和Gallery的有效空間並且在support-v7中有了低版本支持,具體使用方式仍是規規矩矩的適配器加控件模式。咱們先來看看官網的介紹:android
RecyclerView
is a more advanced and flexible version of ListView
. This widget is a container for large sets of views that can be recycled and scrolled very efficiently. Use the RecyclerView
widget when you have lists with elements that change dynamically.ios
RecyclerView比listview更先進更靈活,對於不少的視圖它就是一個容器,能夠有效的重用和滾動。當數據動態變化的時候請使用它。app
RecyclerView
is easy to use, because it provides:ide
RecyclerView使用起來很方便由於它提供:佈局
To use the RecyclerView
widget, you have to specify an adapter and a layout manager. To create an adapter, you extend the RecyclerView.Adapter
class. The details of the implementation depend on the specifics of your dataset and the type of views. For more information, see the examplesbelow.性能
爲了使用RecyclerVIew,你必須指定一個adapter和一個layoutmanager,爲了建立一個adapter,你必須得繼承RecyclerView.Adapter,詳細的實現方法取決與你的數據集和你視圖的類型。flex
Google官方的一個例子:優化
1.佈局文件activity_main.xml動畫
<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" tools:context="${relativePackage}.${activityClass}" > <!-- A RecyclerView with some commonly used attributes --> <android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="horizontal" /> </RelativeLayout>
2.item的佈局文件,就是一個textview
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="Large Text" android:textAppearance="?android:attr/textAppearanceLarge" />
3.主要代碼
3.1 定義控件和佈局
/* * recyclerview提供這些內置的佈局管理器: * linearlayoutmanager 顯示垂直滾動列表或水平的項目。 * gridlayoutmanager 顯示在一個網格項目。 * staggeredgridlayoutmanager 顯示在交錯網格項目。 * 自定義的佈局管理器,須要繼承recyclerview.layoutmanager類。 * * add/remove items時的動畫是默認啓用的。 * 自定義這些動畫須要繼承RecyclerView.ItemAnimator,並實現RecyclerView.setItemAnimator() */
private RecyclerView mRecyclerView; private RecyclerView.Adapter<MyAdapter.ViewHolder> mAdapter; private LinearLayoutManager mLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String [] myDataset = {"Android","ios","jack","tony","window","mac","1234","hehe","495948"}; mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); // improve performance if you know that changes in content // do not change the size of the RecyclerView mRecyclerView.setHasFixedSize(true); // use a linear layout manager mLayoutManager = new LinearLayoutManager(this); //設置RecycleView的顯示方向:(默認爲垂直) 水平 mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); // specify an adapter (see also next example) mAdapter = new MyAdapter(myDataset); mRecyclerView.setAdapter(mAdapter); }
3.2 適配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private String[] mDataset; // Provide a reference to the type of views that you are using // (custom viewholder) public class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(TextView v) { super(v); mTextView = v; } } // Provide a suitable constructor (depends on the kind of dataset) public MyAdapter(String[] 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.my_text_view, parent, false); // set the view's size, margins, paddings and layout parameters ViewHolder vh = new ViewHolder((TextView) 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[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.length; } }
所有代碼:
package com.kale.recyclerviewtest; import android.app.Activity; import android.os.Bundle; 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; public class MainActivity extends Activity { private RecyclerView mRecyclerView; private RecyclerView.Adapter<MyAdapter.ViewHolder> mAdapter; private LinearLayoutManager mLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String [] myDataset = {"Android","ios","jack","tony","window","mac","1234","hehe","495948"}; mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); // improve performance if you know that changes in content // do not change the size of the RecyclerView mRecyclerView.setHasFixedSize(true); // use a linear layout manager mLayoutManager = new LinearLayoutManager(this); //設置RecycleView的顯示方向:(默認爲垂直) 水平 mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); // specify an adapter (see also next example) mAdapter = new MyAdapter(myDataset); mRecyclerView.setAdapter(mAdapter); } public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private String[] mDataset; // Provide a reference to the type of views that you are using // (custom viewholder) public class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(TextView v) { super(v); mTextView = v; } } // Provide a suitable constructor (depends on the kind of dataset) public MyAdapter(String[] 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.my_text_view, parent, false); // set the view's size, margins, paddings and layout parameters ViewHolder vh = new ViewHolder((TextView) 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[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.length; } } }
PS:這個控件好就好在能夠自定義動畫和佈局的方向,在之前還須要咱們本身寫橫向滑動的listview,如今有了它就方便多了。但缺點是沒有listview那麼完善,沒添加頭、尾視圖的功能。再說下它的動畫和佈局類,之後用到的話就知道了。
(1)爲每一個條目位置提供了layout管理器(RecyclerView.setLayoutManager)
(2)爲每一個條目設置了操做動畫(RecyclerView.setItemAnimator)
第二部分
如今咱們知道它是什麼,怎麼用了後。咱們就想本身實現點擊效果,要知道它是不提供itemclicklistner的,因此須要換個思路,在viewHolder中進行實現。其實這樣的分離讓代碼更加簡單和便於維護了。下面的代碼僅僅是概要演示,具體實際操做中咱們徹底能夠利用viewholder來提高滑動的性能,若是viewHolder 中有這個視圖那麼就調出,若是沒有那麼就從新findviewById。
1.viewHolder
viewholder中傳入了一個父視圖,直接綁定監聽器。而後根據須要找到子視圖,進行操做。
/** * @author:Jack Tony * @tips :寫一個viewHolder,用來獲得控件。 * @date :2014-11-1 */ public class MyViewHolder extends RecyclerView.ViewHolder implements OnClickListener,OnLongClickListener{ private TextView mTextView; private int mPosition; public MyViewHolder(View rootView) { super(rootView); //給父控件綁定監聽器 rootView.setOnClickListener(this); //經過findviewbyId找到item中的控件進行設置 mTextView = (TextView)rootView.findViewById(R.id.textView1); ImageView imageView = (ImageView)rootView.findViewById(R.id.imageView1); imageView.setImageResource(R.drawable.kale); } public void setPosition(int position) { mPosition = position; } @Override public boolean onLongClick(View v) { // TODO 自動生成的方法存根 return false; } @Override public void onClick(View v) { // TODO 自動生成的方法存根 Toast.makeText(MainActivity.this, "click "+mPosition, 0).show(); } }
2.Adapter
由於用了本身寫的MyHolder,因此這裏類的泛型中應該傳入本身的這個viewHolder的類名。具體寫法仍是和第一部分中的寫法同樣,甚至簡單了不少。由於這裏咱們只須要關係數據源和位置便可。
/** * @author:Jack Tony * @tips :這裏面徹底能夠根據viewholder是否爲null進行優化 * @date :2014-11-1 */ public class Adapter extends RecyclerView.Adapter<MyViewHolder>{ private String[] mDataset; private MyViewHolder mViewHoder; public Adapter(String[] myDataset) { mDataset = myDataset; } @Override public int getItemCount() { // TODO 自動生成的方法存根 return mDataset.length; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { mViewHoder.mTextView.setText(mDataset[position]); mViewHoder.setPosition(position); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); mViewHoder = new MyViewHolder(v); return mViewHoder; } }
3.Animation
經過繼承RecyclerView.ItemAnimator這個類就能夠給RecylerView添加item動畫,至於具體的實現網上沒有什麼資料。因此我這裏也沒想出怎麼玩的,之後再補上吧。這裏先給出空實現。
public class MyAnim extends RecyclerView.ItemAnimator{ @Override public boolean animateAdd(ViewHolder arg0) { // TODO 自動生成的方法存根 return false; } @Override public boolean animateChange(ViewHolder arg0, ViewHolder arg1, int arg2, int arg3, int arg4, int arg5) { // TODO 自動生成的方法存根 return false; } @Override public boolean animateMove(ViewHolder holder, int fromX, int fromY, int toX, int toY) { // TODO 自動生成的方法存根 return false; } @Override public boolean animateRemove(ViewHolder arg0) { // TODO 自動生成的方法存根 return false; } @Override public void endAnimation(ViewHolder arg0) { // TODO 自動生成的方法存根 } @Override public void endAnimations() { // TODO 自動生成的方法存根 } @Override public boolean isRunning() { // TODO 自動生成的方法存根 return false; } @Override public void runPendingAnimations() { // TODO 自動生成的方法存根 } }
mRecyclerView.setItemAnimator(new MyAnim());
所有代碼:
package com.kale.recyclerviewtest; import android.app.Activity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private RecyclerView mRecyclerView; private Adapter mAdapter; private LinearLayoutManager mLayoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String [] myDataset = {"Android","ios","jack","tony","window","mac","C#","hehe","C++"}; mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); // improve performance if you know that changes in content // do not change the size of the RecyclerView mRecyclerView.setHasFixedSize(true); // use a linear layout manager mLayoutManager = new LinearLayoutManager(this); //設置RecycleView的顯示方向:(默認爲垂直) 水平 mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); // specify an adapter (see also next example) mAdapter = new Adapter(myDataset); mRecyclerView.setAdapter(mAdapter); mRecyclerView.setItemAnimator(new MyAnim()); } /** * @author:Jack Tony * @tips :寫一個viewHolder,用來獲得控件。 * @date :2014-11-1 */ public class MyViewHolder extends RecyclerView.ViewHolder implements OnClickListener,OnLongClickListener{ private TextView mTextView; private int mPosition; public MyViewHolder(View rootView) { super(rootView); //給父控件綁定監聽器 rootView.setOnClickListener(this); //經過findviewbyId找到item中的控件進行設置 mTextView = (TextView)rootView.findViewById(R.id.textView1); ImageView imageView = (ImageView)rootView.findViewById(R.id.imageView1); imageView.setImageResource(R.drawable.kale); } public void setPosition(int position) { mPosition = position; } @Override public boolean onLongClick(View v) { // TODO 自動生成的方法存根 return false; } @Override public void onClick(View v) { // TODO 自動生成的方法存根 Toast.makeText(MainActivity.this, "click "+mPosition, 0).show(); } } /** * @author:Jack Tony * @tips :這裏面徹底能夠根據viewholder是否爲null進行優化 * @date :2014-11-1 */ public class Adapter extends RecyclerView.Adapter<MyViewHolder>{ private String[] mDataset; private MyViewHolder mViewHoder; public Adapter(String[] myDataset) { mDataset = myDataset; } @Override public int getItemCount() { // TODO 自動生成的方法存根 return mDataset.length; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { mViewHoder.mTextView.setText(mDataset[position]); mViewHoder.setPosition(position); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); mViewHoder = new MyViewHolder(v); return mViewHoder; } } public class MyAnim extends RecyclerView.ItemAnimator{ @Override public boolean animateAdd(ViewHolder arg0) { // TODO 自動生成的方法存根 return false; } @Override public boolean animateChange(ViewHolder arg0, ViewHolder arg1, int arg2, int arg3, int arg4, int arg5) { // TODO 自動生成的方法存根 return false; } @Override public boolean animateMove(ViewHolder holder, int fromX, int fromY, int toX, int toY) { // TODO 自動生成的方法存根 return false; } @Override public boolean animateRemove(ViewHolder arg0) { // TODO 自動生成的方法存根 return false; } @Override public void endAnimation(ViewHolder arg0) { // TODO 自動生成的方法存根 } @Override public void endAnimations() { // TODO 自動生成的方法存根 } @Override public boolean isRunning() { // TODO 自動生成的方法存根 return false; } @Override public void runPendingAnimations() { // TODO 自動生成的方法存根 } } }
源碼下載:http://download.csdn.net/detail/shark0017/8110309
參考自:
http://blog.csdn.net/jjwwmlp456/article/details/40540233
http://blog.csdn.net/a396901990/article/details/40187769
http://blog.csdn.net/guxiao1201/article/details/40423361