首先來看看效果吧:

效果預覽.png
本實例來自於慕課網的視屏http://www.imooc.com/video/13046,實現步驟可以自己去觀看視屏,這里只記錄了下實現的代碼。
添加依賴:
(1) 在項目的build.gradle文件中添加下面的依賴
compile 'com.android.support:recyclerview-v7:25.0.0'
(2) 也可以在下圖中自動進行依賴,選擇RecycleView即可。

代碼部分
直接代碼傳送門
MainActivity
public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private MyAdapter mMyAdapter; private int colors[] = {android.R.color.holo_blue_bright,android.R.color.black,android.R.color.holo_red_dark}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initView() { mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerView); mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); mMyAdapter = new MyAdapter(this); mRecyclerView.setAdapter(mMyAdapter); } private void initData() { List<Person> list= new ArrayList<>(); for (int i = 0; i < 20; i++) { Person p = new Person(); int type = (int) (Math.random()*3+1); p.type = type; p.content="content"+1; p.avaterColor = colors[type-1]; p.name = "name"+i; list.add(p); } mMyAdapter.addList(list); mMyAdapter.notifyDataSetChanged(); } }
bean對象Person類
/** * Created by 24540 on 2017/3/13. */ public class Person { public static final int TYPE_ONE = 1; public static final int TYPE_TWO = 2; public static final int TYPE_THREE = 3; protected int type; protected int avaterColor; protected int contentColor; protected String name; protected String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getContentColor() { return contentColor; } public void setContentColor(int contentColor) { this.contentColor = contentColor; } public int getAvaterColor() { return avaterColor; } public void setAvaterColor(int avaterColor) { this.avaterColor = avaterColor; } public int getType() { return type; } public void setType(int type) { this.type = type; } public static int getTypeThree() { return TYPE_THREE; } public static int getTypeTwo() { return TYPE_TWO; } public static int getTypeOne() { return TYPE_ONE; } }
RecycleView的適配器
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private LayoutInflater mLayoutInflater; private List<Person> mList = new ArrayList<>(); private Context mContext; public MyAdapter(Context mContext) { this.mContext = mContext; mLayoutInflater = LayoutInflater.from(mContext); } //使用此方法從獲取數據 public void addList(List<Person> list){ mList.addAll(list); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //根據不同的viewType,創建並返回影響的ViewHolder switch (viewType){ case Person.TYPE_ONE: return new TypeOneHolder(mLayoutInflater.inflate(R.layout.item_type_one,parent,false)); case Person.TYPE_TWO: return new TypeTwoHolder(mLayoutInflater.inflate(R.layout.item_type_two,parent,false)); case Person.TYPE_THREE: return new TypeThreeHolder(mLayoutInflater.inflate(R.layout.item_type_three,parent,false)); } return null; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { //抽象出TypeAbstartViewHolder,所以在進行綁定的時候可以直接調用 ((TypeAbstartViewHolder)holder).bindHolder(mList.get(position)); } @Override public int getItemViewType(int position) { return mList.get(position).getType(); } @Override public int getItemCount() { return mList.size(); } }
關鍵的一點,TypeAbstartViewHolder 抽象出bindHolder方法,優雅實現加載不同item布局,代碼如下:
public abstract class TypeAbstartViewHolder extends RecyclerView.ViewHolder { public TypeAbstartViewHolder(View itemView) { super(itemView); } public abstract void bindHolder(Person person); }
繼承自上面抽象的方法,實現加載不同item布局TypeOneHolder:
public class TypeOneHolder extends TypeAbstartViewHolder { private ImageView avater; private TextView name; public TypeOneHolder(View itemView) { super(itemView); avater = (ImageView) itemView.findViewById(R.id.avater); name = (TextView) itemView.findViewById(R.id.name); } //為ViewHolder綁定數據 @Override public void bindHolder(Person person) { avater.setBackgroundResource(person.getAvaterColor()); name.setText(person.getName()); } }
TypeTwoHolde代碼如下:
public class TypeTwoHolder extends TypeAbstartViewHolder { private ImageView avater; private TextView name; private TextView content; public TypeTwoHolder(View itemView) { super(itemView); avater = (ImageView) itemView.findViewById(R.id.avater); name = (TextView) itemView.findViewById(R.id.name); content = (TextView) itemView.findViewById(R.id.content); } //為ViewHolder綁定數據 @Override public void bindHolder(Person person) { avater.setBackgroundResource(person.getAvaterColor()); name.setText(person.getName()); content.setText(person.getContent()); } }
TypeThreeHolder的代碼如下:
public class TypeThreeHolder extends TypeAbstartViewHolder { private ImageView avater; private TextView name; private TextView content; private ImageView iv; public TypeThreeHolder(View itemView) { super(itemView); avater = (ImageView) itemView.findViewById(R.id.avater); name = (TextView) itemView.findViewById(R.id.name); content = (TextView) itemView.findViewById(R.id.content); iv = (ImageView) itemView.findViewById(R.id.content_color); } //為ViewHolder綁定數據 @Override public void bindHolder(Person person) { avater.setBackgroundResource(person.getAvaterColor()); name.setText(person.getName()); content.setText(person.getContent()); iv.setBackgroundResource(person.getAvaterColor()); } }
xml文件代碼部分:只放出了item_type_three部分的代碼:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:background="@android:color/white" android:layout_width="match_parent" android:gravity="center_vertical" android:layout_height="60dp"> <ImageView android:id="@+id/avater" android:layout_marginLeft="4dp" android:layout_width="40dp" android:layout_height="40dp"/> <LinearLayout android:layout_toRightOf="@id/avater" android:layout_marginLeft="5dp" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/name" android:text="type_one_textview" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/content" android:layout_marginTop="5dp" android:text="type_one_textview" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <ImageView android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:id="@+id/content_color" android:layout_width="100dp" android:layout_height="40dp"/> </RelativeLayout>
通過recycleView實現兩個不同布局混搭,只需要修改mainActivity如下:
public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private MyAdapter mMyAdapter; private int colors[] = {android.R.color.holo_blue_bright, android.R.color.black, android.R.color.holo_red_dark}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initView() { mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerView); //構造參數里面的2表示的是一行有兩列 final GridLayoutManager manager = new GridLayoutManager(this, 2); mRecyclerView.setLayoutManager(manager); manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { int type = mRecyclerView.getAdapter().getItemViewType(position); //若是TYPE_THREE,占用兩列,否則占用一列 if (type == Person.TYPE_THREE) { return manager.getSpanCount(); } else { return 1; } } }); mMyAdapter = new MyAdapter(this); //給布局里的子view添加邊距 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 spanSize = layoutParams.getSpanSize(); int spanIndex = layoutParams.getSpanIndex(); outRect.top = 20; if (spanSize != manager.getSpanCount()) { if (spanIndex == 0) { outRect.right = 0; } else { outRect.right = 10; } } } }); mRecyclerView.setAdapter(mMyAdapter); } private void initData() { List<Person> list = new ArrayList<>(); for (int i = 0; i < 20; i++) { Person p = new Person(); int type = (int) (Math.random() * 3 + 1); p.type = type; p.content = "content" + 1; p.avaterColor = colors[type - 1]; p.name = "name" + i; list.add(p); } mMyAdapter.addList(list); mMyAdapter.notifyDataSetChanged(); } }
效果如圖:

兩種布局.png