最近学习了android5.0中新增的一个组件RecycleView,是用来代替当前的listview开发的,是因为在RecycleView中已经有了viewholder缓存,并且不同的item之间可以设置不同的布局。能非常有效地维护了意见数量有限,滚动大的数据集。使用 RecyclerView当你拥有的数据的集合,它的元素在运行时改变基于用户行为和网络事件的小部件
首先看看RecyclerView的一个小例子:
需要引入:android-support-v7-appcompat.jar
android-v7-RecyclerView.jar来支持低版本的android系统
新建一个my_layout.xml布局文件:里边放置一个RecyclerView
- <android.support.v7.widget.RecyclerView
- android:id="@+id/rvlist"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scrollbars="vertical"
- />
在之前的listview开发中,我们需要自定义viewholder来缓存listView中的数据,而在RecyclerView中,已经封装好了viewholder在adapter中,接下来自定义我们的adapter
- public class MyAdapter2 extends RecyclerView.Adapter<MyAdapter2.ViewHolder>
- {
- // 数据集
- private String[] mDataset;
- public MyAdapter2(String[] dataset)
- {
- super();
- mDataset = dataset;
- }
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)
- {
- // 创建一个View,简单起见直接使用系统提供的布局,就是一个TextView
- View view = View.inflate(viewGroup.getContext(),R.layout.viewholder_item, null);
- // 创建一个ViewHolder
- ViewHolder holder = new ViewHolder(view);
- return holder;
- }
- @Override
- public void onBindViewHolder(ViewHolder viewHolder, int i)
- {
- // 绑定数据到ViewHolder上
- viewHolder.mTextView.setText(mDataset[i]);
- }
- @Override
- public int getItemCount()
- {
- return mDataset.length;
- }
- public static class ViewHolder extends RecyclerView.ViewHolder
- {
- public TextView mTextView;
- public ViewHolder(View itemView)
- {
- super(itemView);
- // mTextView = (TextView) itemView;
- mTextView = (TextView) itemView.findViewById(R.id.view_text_id);
- }
- }
- }
在activity这样调用,并设置adapter
- RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvlist);
- // 创建一个线性布局管理器
- LinearLayoutManager layoutManager = new LinearLayoutManager(this);
- layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
- // 设置布局管理器
- recyclerView.setLayoutManager(layoutManager);
- // 创建数据集
- String[] dataset = new String[100];
- for (int i = 0; i < dataset.length; i++){
- dataset[i] = "item" + i;
- }
- // 创建Adapter,并指定数据集
- MyAdapter2 adapter = new MyAdapter2(dataset);
- // 设置Adapter
- recyclerView.setAdapter(adapter);
- }
运行效果:
在这个例子中只是用到了最基本的布局,下面结合android中新增的CardView和RecycleView实现一个复杂的布局:
先看效果图:
CardView继承自FrameLayout,允许你在card视图中显示信息. CardView也可以设置阴影和圆角。(其实现在很多应用都自定义了Card视图,Google这回将card视图作为基本控件,可以拿来直接使用了)
Layout中为CardView设置圆角使用card_view:cardCornerRadius属性
代码中为CardView设置圆角使用CardView.setRadius方法
为CardView设置背景颜色使用card_view:cardBackgroundColor属性
1.在item布局中引入cardview组件
- <android.support.v7.widget.CardView
- android:id="@+id/cardview_id"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- app:cardCornerRadius="5dp"
- app:cardElevation="0dp" >
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="5dp" >
- <ImageView
- android:id="@+id/image_id"
- android:layout_width="20dp"
- android:layout_height="20dp"
- android:layout_alignParentLeft="true"
- />
- <TextView
- android:id="@+id/text_id"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:textColor="#f89ef5"
- android:textSize="20dp"
- android:layout_centerInParent="true" />
- </RelativeLayout>
- </android.support.v7.widget.CardView>
需要注意的是要在最底层的layout中引入cardview的命名空间:
xmlns:app=http://schemas.android.com/apk/res-auto
要实现不同的item有不同的布局,需要有一个type字段来作为区分,这里,我新建一个UserInfo类,如下:
- public class UserInfo {
- public static final int hasImage = 1;
- public static final int noImage = 2;
- private String mUserName;
- private int userImage;
- int type;
- public String getmUserName() {
- return mUserName;
- }
- public void setmUserName(String mUserName) {
- this.mUserName = mUserName;
- }
- public int getUserImage() {
- return userImage;
- }
- public void setUserImage(int userImage) {
- this.userImage = userImage;
- }
- public int getType() {
- return type;
- }
- public void setType(int type) {
- this.type = type;
- }
- public UserInfo(String mUserName, int type) {
- this.mUserName = mUserName;
- this.type = type;
- }
- public UserInfo(String mUserName, int userImage, int type) {
- this.mUserName = mUserName;
- this.userImage = userImage;
- this.type = type;
- }
- }
hasImage和noImage分别表示该item需不需要加载图片,来加载不同的布局。
接下来看看Adapter的代码:
- public class MyAdapter extends RecyclerView.Adapter<ViewHolder>{
- private List<UserInfo>mList = null;
- private Context context = null;
- public MyAdapter(List<UserInfo> mList, Context context) {
- super();
- this.mList = mList;
- this.context = context;
- // for (int i = 0; i < mList.size(); i++) {
- // Log.d("liuhang","==="+mList.get(i).getmUserName()+"==="+mList.get(i).getUserImage());
- // }
- }
- public void addToList(UserInfo info,int position) {
- mList.add(0, info);
- notifyItemInserted(position);
- notifyDataSetChanged();
- }
- public class TextOnClick implements OnClickListener {
- private int position = 0;
- public TextOnClick(int position) {
- this.position = position;
- }
- @Override
- public void onClick(View v) {
- Toast.makeText(context,"text the name:"+mList.get(position).getmUserName(),1000).show();
- }
- }
- public class ImageOnclick implements OnClickListener {
- private int position = 0;
- public ImageOnclick(int position) {
- this.position = position;
- }
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Toast.makeText(context,"image the imageId:"+mList.get(position).getUserImage(),1000).show();
- }
- }
- public class ItemOnClick implements OnItemClickListener {
- @Override
- public void onItemClick(AdapterViewCompat<?> arg0, View arg1, int arg2,
- long arg3) {
- // TODO Auto-generated method stub
- Toast.makeText(context,"you choose the item",1000).show();
- }
- }
- @Override
- public int getItemCount() {
- return mList.size();
- }
- public class TextViewHolder extends RecyclerView.ViewHolder {
- public TextView textView = null;
- public TextViewHolder(View view) {
- super(view);
- this.textView = (TextView) view.findViewById(R.id.text_id);
- }
- }
- public class ImageTextViewHolder extends RecyclerView.ViewHolder {
- public ImageView imageView = null;
- public TextView textView = null;
- public ImageTextViewHolder(View view) {
- super(view);
- this.imageView = (ImageView) view.findViewById(R.id.image_id);
- this.textView = (TextView) view.findViewById(R.id.text_id);
- }
- }
- @Override
- public int getItemViewType(int position) {
- // TODO Auto-generated method stub
- return mList.get(position).getType();
- }
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- switch (getItemViewType(position)) {
- case UserInfo.hasImage:
- ImageTextViewHolder imageTextViewHolder = (ImageTextViewHolder) holder;
- imageTextViewHolder.imageView.setImageResource(mList.get(position).getUserImage());
- imageTextViewHolder.textView.setText(mList.get(position).getmUserName());
- imageTextViewHolder.textView.setOnClickListener(new TextOnClick(position));
- imageTextViewHolder.imageView.setOnClickListener(new ImageOnclick(position));
- break;
- case UserInfo.noImage:
- TextViewHolder textViewHolder = (TextViewHolder) holder;
- textViewHolder.textView.setText(mList.get(position).getmUserName());
- textViewHolder.textView.setOnClickListener(new TextOnClick(position));
- }
- }
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
- ViewHolder holder = null;
- View view = null;
- switch (type) {
- case UserInfo.hasImage:
- view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_text_image_item,null);
- holder = new ImageTextViewHolder(view);
- break;
- case UserInfo.noImage:
- view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_text_item,null);
- holder = new TextViewHolder(view);
- break;
- }
- <a target=_blank href="http://download.csdn.net/detail/mockingbirds/8312357">源码下载</a>
- return holder;
- }
- }
在activity中这样调用:
- RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_id);
- recyclerView.setHasFixedSize(true);
- LinearLayoutManager linaLayout = new LinearLayoutManager(this);
- linaLayout.setOrientation(1);
- recyclerView.setLayoutManager(linaLayout);
- recyclerView.getRecycledViewPool().setMaxRecycledViews(0, 10);
- int[]userImage = {R.drawable.icon08,R.drawable.icon00,R.drawable.icon01,
- R.drawable.icon02,R.drawable.icon03,R.drawable.icon04,
- R.drawable.icon05,R.drawable.icon06,R.drawable.icon07};
- List<UserInfo>userList = new ArrayList<UserInfo>();
- int position = 0;
- for (int i = 0; i < 35; i++) {
- position = (int) (Math.random() * 8);
- UserInfo userInfo1 = new UserInfo("zhangsan"+i,2);
- UserInfo userInfo2 = new UserInfo("lisi"+i,userImage[position],1);
- userList.add(userInfo1);
- userList.add(userInfo2);
- }
- final MyAdapter adapter= new MyAdapter(userList, this);
- recyclerView.setAdapter(adapter);
- recyclerView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Toast.makeText(MyActivity.this,"you choose the item",1000).show();
- }
- });
- Button button = (Button) findViewById(R.id.add);
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- adapter.addToList(new UserInfo("new add"+ newAdd++, 2),0);
- }
- });