如何实现ListView和GridView混合的效果,效果图:
一、可以使用以下方式:
1、以往的方式
1)使用ListView内嵌GridView。(相信大家都使用过,在此不做描述)
2、RecycleView
1)使用单个RecycleView。
2)使用RecycleView内嵌RecycleView。
二、使用单个RecycleView。
1、如下图,由于使用一个RecycleView,我们可以把每个一红矩形看成一个item,那么就会有item1(标题)占整个屏幕的宽度,item2(内容)占屏幕的宽度的1/3。
2、核心:通过GridLayoutManager实现不同item占用不同的屏幕宽度,GridLayoutManager有一个方法setSpanSizeLookup,可以设置GridView中每项的所占的比例。
//3表示每行最多有3个item
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
//return 3 表示这个item占满一行,这里是标题item
//return 1 表示这个item占满行1/3,这里是标题的子item
if (datas.get(position).getType() == 1)
return 3;
return 1;
}
});
3、了解完核心思想,我们看看代码实现:
1)Activity布局:
<android.support.v7.widget.RecyclerView
android:id="@+id/jd2b_goods_category_elv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f9f9f9"
android:overScrollMode="never" />
2)item(标题)布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:percent="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/public_space_value_10">
<TextView
android:id="@+id/item_category_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
android:textColor="@color/jd2b_color_333333" />
<ImageView
android:layout_width="wrap_content"
android:src="@mipmap/jd2b_arr_down_big_ccc_click"
android:layout_centerVertical="true"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" />
</RelativeLayout>
3)item(内容)布局:
<?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="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/item_category_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
android:textColor="@color/jd2b_color_333333" />
</LinearLayout>
4)Activity初始化recycleView代码:
RecyclerView jd2b_goods_category_elv = findViewById(R.id.jd2b_goods_category_elv);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (datas.get(position).getType() == 1)
return 3;
return 1;
}
});
jd2b_goods_category_elv.setLayoutManager(gridLayoutManager);
rvAdapter = new JD2BRvAdapter(mActivity);
jd2b_goods_category_elv.setAdapter(rvAdapter);
//获取到服务器数据后更新adapter
datas.clear();
for (ProductCategoriesBackObject productCategory : productCategories) {
productCategory.setType(1);
datas.add(productCategory);
if (productCategory.getSubCategorys().size() > 0)
for (ProductCategoriesBackObject subCategory : productCategory.getSubCategorys()) {
subCategory.setType(2);
datas.add(subCategory);
}
}
rvAdapter.setCategoriesBackObjects(datas);
5)adapter
public class JD2BRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ProductCategoriesBackObject> categoriesBackObjects;
private Context context;
public JD2BRvAdapter(Context context) {
categoriesBackObjects = new ArrayList<>();
this.context = context;
}
public void setCategoriesBackObjects(List<ProductCategoriesBackObject> categoriesBackObjects) {
if (categoriesBackObjects != null) {
this.categoriesBackObjects.clear();
this.categoriesBackObjects.addAll(categoriesBackObjects);
notifyDataSetChanged();
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == 1) {
//标题item
View view = LayoutInflater.from(context).inflate(R.layout.jd2b_item_category_title, parent, false);
return new TitleViewHolder(view);
} else {
//标题子项
View view = LayoutInflater.from(context).inflate(R.layout.jd2b_item_category_item, parent, false);
return new ViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ProductCategoriesBackObject categoriesBackObject = categoriesBackObjects.get(position);
if (categoriesBackObject != null) {
if (getItemViewType(position) == 1) {
//标题item
((TitleViewHolder) holder).nameTV.setText(categoriesBackObject.getCategoryName());
} else {
//标题子项
((ViewHolder) holder).nameTV.setText(categoriesBackObject.getCategoryName());
}
}
}
@Override
public int getItemCount() {
return categoriesBackObjects.size();
}
@Override
public int getItemViewType(int position) {
return categoriesBackObjects.get(position).getType();
}
public class TitleViewHolder extends RecyclerView.ViewHolder {
public TextView nameTV;
public TitleViewHolder(View view) {
super(view);
nameTV = (TextView) view.findViewById(R.id.item_category_title);
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView nameTV;
public ViewHolder(View view) {
super(view);
nameTV = (TextView) view.findViewById(R.id.item_category_name);
}
}
}
6)数据对象ProductCategoriesBackObject
public class ProductCategoriesBackObject {
//分类id
private String id;
//分类名称
private String categoryName;
//分类编号
private String categoryCode;
//分类等级
private String level;
//父id
private String parentid;
private int type;
private ArrayList<ProductCategoriesBackObject> subCategorys;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryCode() {
return categoryCode;
}
public void setCategoryCode(String categoryCode) {
this.categoryCode = categoryCode;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getParentid() {
return parentid;
}
public void setParentid(String parentid) {
this.parentid = parentid;
}
public ArrayList<ProductCategoriesBackObject> getSubCategorys() {
return subCategorys;
}
public void setSubCategorys(ArrayList<ProductCategoriesBackObject> subCategorys) {
this.subCategorys = subCategorys;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
7)至此我们已经学会通过单个RecycleView的GridLayoutManager去实现ListView和GridView混合的效果,下面我们一起去看看如何通过RecycleView内嵌RecycleView去实现这个效果。
三、使用RecycleView内嵌RecycleView。(跟listview内嵌gridview类似)
1、我们可以把标题和内容看成是一个item,再把item里面的内容部分,使用一个recycleview去实现即可。
2、RecycleView内嵌RecycleView比较简单,直接上代码:
1)Activity布局:
<android.support.v7.widget.RecyclerView
android:id="@+id/jd2b_goods_category_elv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f9f9f9"
android:overScrollMode="never" />
2)item布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:percent="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/public_space_value_10">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/item_category_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
android:textColor="@color/jd2b_color_333333" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@mipmap/jd2b_arr_down_big_ccc_click" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/jd2b_goods_category_item_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f9f9f9"
android:overScrollMode="never" />
</LinearLayout>
3)item里面的recycleview的item的布局:
<?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="wrap_content"
android:background="@drawable/jd2b_corners_board_333333_shape"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/item_category_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
android:textColor="@color/jd2b_color_333333" />
</LinearLayout>
4)Activity初始化recycleView代码:
RecyclerView jd2b_goods_category_elv = findViewById(R.id.jd2b_goods_category_elv);
LinearLayoutManager leftLinearLayoutManager = new LinearLayoutManager(mActivity);
leftLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
jd2b_goods_category_elv.setLayoutManager(leftLinearLayoutManager);
rvAdapter = new JD2BRvAdapter(mActivity);
jd2b_goods_category_elv.setAdapter(rvAdapter);
//获取到服务器数据后更新adapter
datas.clear();
for (ProductCategoriesBackObject productCategory : productCategories) {
datas.add(productCategory);
}
rvAdapter.setCategoriesBackObjects(datas);
5)adapter:
public class JD2BRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ProductCategoriesBackObject> categoriesBackObjects;
private Context context;
public JD2BRvAdapter(Context context) {
categoriesBackObjects = new ArrayList<>();
this.context = context;
}
public void setCategoriesBackObjects(List<ProductCategoriesBackObject> categoriesBackObjects) {
if (categoriesBackObjects != null) {
this.categoriesBackObjects.clear();
this.categoriesBackObjects.addAll(categoriesBackObjects);
notifyDataSetChanged();
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.jd2b_item_category_title, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ProductCategoriesBackObject categoriesBackObject = categoriesBackObjects.get(position);
if (categoriesBackObject != null) {
ViewHolder viewHolder = ((ViewHolder) holder);
viewHolder.nameTV.setText(categoriesBackObject.getCategoryName());
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 4);
viewHolder.itemRV.setLayoutManager(gridLayoutManager);
JD2BItemRvAdapter rvAdapter = new JD2BItemRvAdapter(context);
viewHolder.itemRV.setAdapter(rvAdapter);
rvAdapter.setCategoriesBackObjects(categoriesBackObject.getSubCategorys());
}
}
@Override
public int getItemCount() {
return categoriesBackObjects.size();
}
@Override
public int getItemViewType(int position) {
return categoriesBackObjects.get(position).getType();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView nameTV;
private RecyclerView itemRV;
public ViewHolder(View view) {
super(view);
nameTV = (TextView) view.findViewById(R.id.item_category_title);
itemRV = (RecyclerView) view.findViewById(R.id.jd2b_goods_category_item_rv);
}
}
}
6)item里面的recycleview的adapter:
public class JD2BItemRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ProductCategoriesBackObject> categoriesBackObjects;
private Context context;
public JD2BItemRvAdapter(Context context) {
categoriesBackObjects = new ArrayList<>();
this.context = context;
}
public void setCategoriesBackObjects(List<ProductCategoriesBackObject> categoriesBackObjects) {
if (categoriesBackObjects != null) {
this.categoriesBackObjects.clear();
this.categoriesBackObjects.addAll(categoriesBackObjects);
notifyDataSetChanged();
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.jd2b_item_category_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ProductCategoriesBackObject categoriesBackObject = categoriesBackObjects.get(position);
if (categoriesBackObject != null) {
((ViewHolder) holder).nameTV.setText(categoriesBackObject.getCategoryName());
}
}
@Override
public int getItemCount() {
return categoriesBackObjects.size();
}
@Override
public int getItemViewType(int position) {
return categoriesBackObjects.get(position).getType();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView nameTV;
public ViewHolder(View view) {
super(view);
nameTV = (TextView) view.findViewById(R.id.item_category_name);
}
}
}
7)数据对象ProductCategoriesBackObject
public class ProductCategoriesBackObject {
//分类id
private String id;
//分类名称
private String categoryName;
//分类编号
private String categoryCode;
//分类等级
private String level;
//父id
private String parentid;
private int type;
private ArrayList<ProductCategoriesBackObject> subCategorys;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryCode() {
return categoryCode;
}
public void setCategoryCode(String categoryCode) {
this.categoryCode = categoryCode;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String getParentid() {
return parentid;
}
public void setParentid(String parentid) {
this.parentid = parentid;
}
public ArrayList<ProductCategoriesBackObject> getSubCategorys() {
return subCategorys;
}
public void setSubCategorys(ArrayList<ProductCategoriesBackObject> subCategorys) {
this.subCategorys = subCategorys;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
8)至此,RecyclerView实现ListView和GridView混合的效果的两种方式都已经学完了。