第一部分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