最近在看慕课网的学习视频看见了一个用recyclerview加载不同的item看了看就按着他的原理写了下来成了一个demo,希望能帮助有用的人。
慕课地址:http://www.imooc.com/learn/731
先看下效果图
三个不同的布局,实际情况按开发需求来写
item_one.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="150dp"> <ImageView android:id="@+id/one_avatar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:scaleType="centerCrop" app:srcCompat="@mipmap/ic_launcher" /> <TextView android:id="@+id/one_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" tools:text="名称" /> </LinearLayout>
item_two.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="150dp" android:orientation="vertical"> <ImageView android:id="@+id/two_avatar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" app:srcCompat="@mipmap/ic_launcher" /> <TextView android:id="@+id/two_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" tools:text="名称" /> <TextView android:id="@+id/two_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="哈哈" tools:text="内容" /> </LinearLayout>
item_three.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="100dp" android:orientation="horizontal"> <ImageView android:id="@+id/three_avatar" android:layout_width="100dp" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="10dp" app:srcCompat="@mipmap/ic_launcher" /> <TextView android:id="@+id/three_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_centerVertical="true" tools:text="名称" /> </RelativeLayout>
三个布局对应着有三个viewHolder(当然如果有更好的写法也欢迎留下)这里只举一个例子其他都基本一样。
package com.nz.zdd.zlistview.holder; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.nostra13.universalimageloader.core.ImageLoader; import com.nz.zdd.zlistview.R; import com.nz.zdd.zlistview.entity.CargoMessage; import com.nz.zdd.zlistview.entity.CargoMessageOne; import com.nz.zdd.zlistview.utils.ImageOption; /** * Created by zdd on 2016/10/18. */ public class TypeOneHolder extends TypeAbstractViewHolder<CargoMessageOne> { public TextView name; public ImageView avatar; public TypeOneHolder(View itemView) { super(itemView); avatar = (ImageView) itemView.findViewById(R.id.one_avatar); name = (TextView) itemView.findViewById(R.id.one_name); } @Override public void bindViewHolder(CargoMessageOne cargoMessage) { name.setText(cargoMessage.name); ImageLoader.getInstance().displayImage(cargoMessage.ImageUrl,avatar,ImageOption.setOptions()); } }
这里是adapter,通过getItemType来获取布局样式从而判断要加的布局样子;
package com.nz.zdd.zlistview.adapter; import android.content.Context; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.ViewGroup; import com.nz.zdd.zlistview.R; import com.nz.zdd.zlistview.entity.CargoMessage; import com.nz.zdd.zlistview.entity.CargoMessageOne; import com.nz.zdd.zlistview.entity.CargoMessageThree; import com.nz.zdd.zlistview.entity.CargoMessageTwo; import com.nz.zdd.zlistview.holder.TypeAbstractViewHolder; import com.nz.zdd.zlistview.holder.TypeOneHolder; import com.nz.zdd.zlistview.holder.TypeThreeHolder; import com.nz.zdd.zlistview.holder.TypeTwoHolder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by zdd on 2016/10/18. */ public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public static final int type_one = 1; public static final int type_two = 2; public static final int type_three = 3; private LayoutInflater layoutInflater; private List<CargoMessageOne> listOne; private List<CargoMessageTwo> listTwo; private List<CargoMessageThree> listThree; private List<Integer> types = new ArrayList<>(); private Map<Integer, Integer> mPositions = new HashMap<>(); public RecyclerViewAdapter(Context context, List<CargoMessageOne> listOne, List<CargoMessageTwo> listTwo, List<CargoMessageThree> listThree) { layoutInflater = LayoutInflater.from(context); this.listOne = listOne; this.listTwo = listTwo; this.listThree = listThree; addlistBytype(type_one, listOne); addlistBytype(type_two, listTwo); addlistBytype(type_three, listThree); } public void addlistBytype(int type, List list) { mPositions.put(type, types.size()); for (int i = 0; i < list.size(); i++) { types.add(type); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case CargoMessage.type_one: return new TypeOneHolder(layoutInflater.inflate(R.layout.item_type_one, parent, false)); case CargoMessage.type_two: return new TypeTwoHolder(layoutInflater.inflate(R.layout.item_type_two, parent, false)); case CargoMessage.type_three: return new TypeThreeHolder(layoutInflater.inflate(R.layout.item_type_three, parent, false)); } return null; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { // ((TypeAbstractViewHolder) holder).bindViewHolder(listData.get(position)); int intemtype = getItemViewType(position); int realPosition = position - mPositions.get(intemtype); switch (intemtype) { case CargoMessage.type_one: ((TypeOneHolder) holder).bindViewHolder(listOne.get(realPosition)); break; case CargoMessage.type_two: ((TypeTwoHolder) holder).bindViewHolder(listTwo.get(realPosition)); break; case CargoMessage.type_three: ((TypeThreeHolder) holder).bindViewHolder(listThree.get(realPosition)); break; } } @Override public int getItemViewType(int position) { return types.get(position); } @Override public int getItemCount() { return types.size(); } }
最后通过activity调用设置adapter就可以了
private void initView() { //添加数据 initData(); mRecyclerView = (RecyclerView) findViewById(R.id.recyDemo); //单纯的列表布局 //mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); final GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2); //合并单元格 gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { int type = mRecyclerView.getAdapter().getItemViewType(position); if (type == CargoMessage.type_three) { return gridLayoutManager.getSpanCount(); } else { return 1; } } }); //设置item的间隔 mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() { @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams(); int size = layoutParams.getSpanSize(); int indext = layoutParams.getSpanIndex(); outRect.top = 10; if (size != gridLayoutManager.getSpanCount()) { if (indext == 1) { outRect.left = 10; } else { outRect.right = 10; } } } }); mRecyclerView.setLayoutManager(gridLayoutManager); mRecyclerAdapter = new RecyclerViewAdapter(this, listOne, listTwo, listThree); mRecyclerView.setAdapter(mRecyclerAdapter); mRecyclerAdapter.notifyDataSetChanged(); }
。。。。。。。。。。。。。。。。。。。。。
后来自己加了imageloader的图片缓存加载。
源码中还有自定义的listview下拉刷新,更换启动的activity就可以用了,
源码下载