在Listview中使用了很久的viewholder、setTag、getTag来实现Item复用后, Google大大终于看不下去了。推出了明日之星RecyclerView,现已加入support.v7豪华套餐。顾名思义,RecyclerView本身是不管怎么布局的。它本身只负责,加载看得见的viewHolder,释放看不见的viewHolder。这一功能就代替掉了,ListView中麻烦的Item复用设计。而对于布局的控制,RecyclerView则依赖于LayoutManager。下面,我用一个简单的demo,记录下RecyclerView的用法。
一、如何加入support.v7包(Android Studio中)。
方法1:右键项目->Open Module Settings->Dependencies->绿色加号->Library dependency -> recyclerview-v7->OK
方法2:
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.gradle
二、我自定义了MyRecyclerView继承RecyclerView,这不是必需的,我只是为了方便以后扩展。
三、完成布局文件中 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" 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>
四、完成Item的布局 normal_item_layout.xml
<?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>
五、完成Item的ViewHolder,并给予子控件实例。 MyRecyclerViewHold.java
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()); } }
六、实现RecyclerView的适配器RecyclerViewAdapter。 MyRecyclerViewAdapter.java
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中包含了四个方法,它们分别是:
1、public int getItemViewType(int position) 获取Item的类型,默认是0。
2、public MyRecyclerViewHold onCreateViewHolder(ViewGroup parent, int viewType) 生成Item的ViewHolder
3、public void onBindViewHolder(MyRecyclerViewHold holder, int position)将Item的ViewHolder与数据List连接
4、public int getItemCount()获取Item总数
七、在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(" "+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!