如何實現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混合的效果的兩種方式都已經學完了。