是否可以在Recycler视图适配器中使用三种视图类型?

时间:2016-07-01 07:27:57

标签: android android-recyclerview recycler-adapter

public class StoreDetailAdapter extends RecyclerView.Adapter<StoreDetailAdapter.MyViewHolder> {
    private final int VIEW_TYPE_STORE_HEAD = 0;
    private final int VIEW_TYPE_CAT = 1;
    private final int VIEW_TYPE_PROD = 2;

    private List<Store.ProductType.ProductList> mPopularProducts = new ArrayList<>();
    private List<Store.ProductType.ProductList> mPurchasedProducts = new ArrayList<>();
    private CategoryListAdapter mCategoryAdapter;
    private ProductCollectionAdapter mProductCollectionAdapter;
    private Context mContext;
    private List<Category> mCategories = new ArrayList<>();
    private List<InStore> inStoreList = new ArrayList<>();

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView categoryName;
        public TwoWayView items;
        LinearLayout containerHeading;
        FrameLayout containerHeaderImage;
        ImageView imageView;
        private Store mStore;

        public MyViewHolder(View view) {
            super(view);
            items = (TwoWayView) view.findViewById(R.id.items_list);
            categoryName = (TextView) view.findViewById(R.id.category_name);
            containerHeading = (LinearLayout) view.findViewById(R.id.container_linear_layout_heading);
            containerHeaderImage = (FrameLayout) view.findViewById(R.id.container_frame_layout_image);
            imageView = (ImageView) view.findViewById(R.id.image_store_icon);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if(isFromMall){
            if(position == 0)
                return VIEW_TYPE_STORE_HEAD;
            else if(position == 1)
                return VIEW_TYPE_CAT;
            else if(position == 2)
                return VIEW_TYPE_PROD;
        } else {
            return position==0 ? VIEW_TYPE_CAT :VIEW_TYPE_PROD;
        }
        return 0;
    }

    public StoreDetailAdapter(Context context, List<Category> categories, List<Store.ProductType.ProductList> products, Store.ProductType popularType, Store store) {
        mContext = context;
        mCategoryAdapter = new CategoryListAdapter(mContext, R.layout.view_category_item);
        mCategoryAdapter.clear();
        mCategories = categories;
        mCategoryAdapter.notifyDataSetChanged();
        mPopularProducts = products;
        notifyDataSetChanged();
        mStore =store;
    }

    public StoreDetailAdapter(Context context, List<Category> categories, List<Store.ProductType.ProductList> popularProducts, List<Store.ProductType.ProductList> purchasedProducts, Store.ProductType popularType, Store.ProductType purchasedType) {
        mContext = context;
        mCategoryAdapter = new CategoryListAdapter(mContext, R.layout.view_category_item);
        mCategoryAdapter.clear();
        mCategories = categories;
        mCategoryAdapter.notifyDataSetChanged();
        mPopularProducts = popularProducts;
        mPurchasedProducts = purchasedProducts;
        notifyDataSetChanged();
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.view_home_list_item, parent, false);
        return new MyViewHolder(itemView);
    }



    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        switch (getItemViewType(position)) {

            case VIEW_TYPE_STORE_HEAD:
                holder.containerHeaderImage.setVisibility(View.VISIBLE);
                holder.containerHeading.setVisibility(View.GONE);
                holder.items.setVisibility(View.GONE);
                Picasso.with(getContext())
                .load(mStore.getImageUriNew(Store.IMAGE_MD))
                .into(holder.imageView);
                break;

            case VIEW_TYPE_CAT:
                holder.containerHeaderImage.setVisibility(View.GONE);
                holder.containerHeading.setVisibility(View.GONE);
                mCategoryAdapter = new CategoryListAdapter(mContext, R.layout.view_category_item);
                holder.items.setAdapter(mCategoryAdapter);
                holder.items.setOnItemClickListener(mCategoryClickListener);
                mCategoryAdapter.addAll(mCategories);
                break;

            case VIEW_TYPE_PROD:
                if(mPopularProducts == null || mPopularProducts.isEmpty()){
                    holder.containerHeading.setVisibility(View.GONE);
                    break;
                }
                holder.containerHeaderImage.setVisibility(View.GONE);
                int pos = isFromMall()?position-2:position-1;
                if (pos < mPurchasedProducts.size()) {
                    holder.categoryName.setText(mPurchasedProducts.get(pos).getTitle());
                    break;
                }
                holder.categoryName.setText(mPopularProducts.get(pos).getTitle());
                inStoreList = mPopularProducts.get(pos).getInStores();
                mProductCollectionAdapter = new ProductCollectionAdapter(getContext(), R.layout.view_store_detail_product_list_item);
                holder.items.setAdapter(mProductCollectionAdapter);
                holder.items.setOnItemClickListener(mProductClickListener);
                mProductCollectionAdapter.addAll(inStoreList);
                mProductCollectionAdapter.notifyDataSetChanged();
                break;
        }
    }

    @Override
    public int getItemCount() {
        return isFromMall?2:1
                + mPopularProducts.size()
                + mPurchasedProducts.size();
    }

    private AdapterView.OnItemClickListener mCategoryClickListener = (parent, view, position, id) -> {
       //click implementation goes here
        }
    };

    private AdapterView.OnItemClickListener mProductClickListener = (parent, view, position, id) -> {
       //todo click
    };

}

上面的代码有错误吗? case position == 2未执行getItemViewType()? 我尝试调试,但position始终为01 我在这里使用单一布局,单视图持有人。如果isFromMall条件为true,我正在做的是显示/隐藏视图。

3 个答案:

答案 0 :(得分:2)

您可以拥有任意数量的ViewTypes。只需确保getItemViewType始终为您返回类型。并且您的逻辑可以为那些生成ViewHolder s。请记住,一旦改变上述条件,就必须通知适配器有关整个数据集的更改。

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    @Override
    public int getItemViewType(int position) {
        // return your viewType here. make sure each position results in a viewType. 
        // otherwise you may end up in exceptions as no ViewHolder can be generated afterwards
        return yourViewType;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         //here you create the ViewHolders for the different viewTypes you have generated abvoe
         switch (viewType) {
             case 0: return new ViewHolder0(...);
             case 2: return new ViewHolder2(...);
             ...
         }
    }
}

我创建了一个库来处理所有这些事情,并强制正确使用。您可以在此处找到它:FastAdapter

答案 1 :(得分:1)

试试这个

 @Override
public int getItemViewType(int position) {
    if(isFromMall){
        if(position == 0)
            return 2;
        else if(position == 1)
            return 1;
        else if(position == 2)
            return 0;
    } else {
        return 0;
    }
    return 0;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = null;
    if (viewType == 0) {

        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewpager, parent, false);
        return new CreateTwoViewHolder(view);
    }
    if (viewType == 1) {

        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.expandcategoryview, parent, false);
        return new CreateThreeeViewHolder(view);
    }
    if (viewType == 2) {

        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewpager, parent, false);
        return new CreatefourViewHolder(view);
    }
    view = LayoutInflater.from(parent.getContext()).inflate(R.layout.categoryview, parent, false);
    return new CreateOneViewHolder(view);

}

答案 2 :(得分:0)

修复了再见只有两种视图类型:)

@覆盖         public void onBindViewHolder(MyViewHolder holder,int position){             switch(getItemViewType(position)){

            case VIEW_TYPE_CAT:
                if (isFromMall) {
                    holder.containerHeaderImage.setVisibility(View.VISIBLE);
                    Picasso.with(getContext())
                            .load(store.getImageUriNew(Store.IMAGE_MD))
                            .into(holder.imageView);
                } else {
                    holder.containerHeaderImage.setVisibility(View.GONE);
                }
                holder.containerHeading.setVisibility(View.GONE);
                mCategoryAdapter = new CategoryListAdapter(mContext, R.layout.view_category_item);
                holder.items.setAdapter(mCategoryAdapter);
                holder.items.setOnItemClickListener(mCategoryClickListener);
                mCategoryAdapter.addAll(mCategories);
                break;

            case VIEW_TYPE_PROD:
                if (mPopularProducts == null || mPopularProducts.isEmpty()) {
                    holder.containerHeading.setVisibility(View.GONE);
                    break;
                }
                holder.containerHeaderImage.setVisibility(View.GONE);
                int pos = position - 1;
                if (pos < mPurchasedProducts.size()) {
                    holder.categoryName.setText(mPurchasedProducts.get(pos).getTitle());
                    break;
                }
                holder.categoryName.setText(mPopularProducts.get(pos).getTitle());
                inStoreList = mPopularProducts.get(pos).getInStores();
                mProductCollectionAdapter = new ProductCollectionAdapter(getContext(), R.layout.view_store_detail_product_list_item);
                holder.items.setAdapter(mProductCollectionAdapter);
                holder.items.setOnItemClickListener(mProductClickListener);
                mProductCollectionAdapter.addAll(inStoreList);
                mProductCollectionAdapter.notifyDataSetChanged();
                break;
        }
    }