You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:Firestore商品数据按分类名排序展示到嵌套Recyclerview问题

问题原因

你的现有代码存在两个核心逻辑错误:

  1. 外层分类Adapter的数据源是所有商品列表,导致有多少个商品就生成多少个外层分类条目,没有对分类做去重处理。
  2. 每个外层分类条目绑定数据时,将全部商品列表直接传给内层商品Adapter,导致每个分类下都展示所有商品,没有过滤当前分类对应的商品。

解决方案

步骤1:调整Firestore数据拉取后的分组逻辑

修改HomeFragment中的getproductsfromcats方法,对拉取到的商品按分类字段分组,生成去重的分类列表和分类对应商品的映射关系:

private void getproductsfromcats() {
    Query query = collectionReference.orderBy("ItemCategory");
    query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
            productsModelList2.clear();
            for (QueryDocumentSnapshot queryDocumentSnapshot : queryDocumentSnapshots) {
                ProductsModel productsModel = queryDocumentSnapshot.toObject(ProductsModel.class);
                productsModelList2.add(productsModel);
            }
            // 按分类分组,保留分类排序
            Map<String, List<ProductsModel>> categoryGroupMap = new LinkedHashMap<>();
            for (ProductsModel product : productsModelList2) {
                String category = product.getItemCategory();
                if (!categoryGroupMap.containsKey(category)) {
                    categoryGroupMap.put(category, new ArrayList<>());
                }
                categoryGroupMap.get(category).add(product);
            }
            // 传入分组后的数据给外层Adapter
            productsAdapterbyCategory = new ProductsAdapterbyCategory(
                    new ArrayList<>(categoryGroupMap.keySet()),
                    categoryGroupMap,
                    view.getContext()
            );
            product_items_for_cat.setAdapter(productsAdapterbyCategory);
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(view.getContext(), "拉取失败", Toast.LENGTH_SHORT).show();
        }
    });
}

步骤2:修改外层分类Adapter逻辑

调整ProductsAdapterbyCategory的数据源结构,适配分组后的数据:

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chattthedev.shoppingguskara.Activities.Models.ProductsModel;
import com.chattthedev.shoppingguskara.R;

import java.util.List;
import java.util.Map;

public class ProductsAdapterbyCategory extends 
RecyclerView.Adapter<ProductsAdapterbyCategory.ViewHolderForProducts> {

    List<String> categoryList;
    Map<String, List<ProductsModel>> categoryProductMap;
    Context context;

    public ProductsAdapterbyCategory(List<String> categoryList, Map<String, List<ProductsModel>> categoryProductMap, Context context) {
        this.categoryList = categoryList;
        this.categoryProductMap = categoryProductMap;
        this.context = context;
    }

    @NonNull
    @Override
    public ViewHolderForProducts onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.singleforitembycat, parent, false);
        return new ViewHolderForProducts(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolderForProducts holder, int position) {
        String currentCategory = categoryList.get(position);
        holder.catnameinprod.setText(currentCategory);
        // 仅传入当前分类对应的商品给内层Adapter
        List<ProductsModel> currentProducts = categoryProductMap.get(currentCategory);
        ProductsAdapter2 productsAdapter2 = new ProductsAdapter2(currentProducts, context);
        holder.recyclerViewinprod.setHasFixedSize(true);
        holder.recyclerViewinprod.setLayoutManager(new LinearLayoutManager(context, RecyclerView.HORIZONTAL, false));
        holder.recyclerViewinprod.setAdapter(productsAdapter2);
        holder.recyclerViewinprod.setNestedScrollingEnabled(false);
    }

    @Override
    public int getItemCount() {
        return categoryList != null ? categoryList.size() : 0;
    }

    public class ViewHolderForProducts extends RecyclerView.ViewHolder {
        public TextView catnameinprod;
        public Button viewmoreinprod;
        public RecyclerView recyclerViewinprod;

        public ViewHolderForProducts(@NonNull View itemView) {
            super(itemView);
            catnameinprod = itemView.findViewById(R.id.catnameforfetch);
            viewmoreinprod = itemView.findViewById(R.id.buttviewmoreitem);
            recyclerViewinprod = itemView.findViewById(R.id.recyclerprodfetch);
        }
    }
}

步骤3:验证排序效果

你原有查询中已经添加了orderBy("ItemCategory"),分组使用的LinkedHashMap会保留Firestore返回的分类排序顺序,不需要额外做本地排序处理。


内容的提问来源于stack exchange,提问作者ChattTheDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 03:45:02