首先来看看效果吧:
本实例来自于慕课网的视屏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(); } }
效果如图: