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

Java中如何复用单个RecyclerView Adapter适配多种布局?

复用现有RecyclerView Adapter适配多种布局的方案

当然不需要新建Adapter啦!我们可以利用RecyclerView自带的**多视图类型(Multiple View Types)**机制,轻松改造你现有的BookRecyclerViewAdapter,让它同时适配你的可展开CardView和另一种布局。下面我结合你的代码一步步说明具体修改步骤:

步骤1:定义视图类型常量

首先在BookRecyclerViewAdapter里添加两个常量,用来区分两种不同的布局:

public class BookRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 
    // 视图类型常量:可展开CardView布局
    private static final int VIEW_TYPE_EXPANDABLE_CARD = 0;
    // 视图类型常量:新的另一种布局
    private static final int VIEW_TYPE_OTHER_LAYOUT = 1;
    
    private ArrayList<Book> books = new ArrayList<>(); 
    private Context context;
    // 保存当前要使用的视图类型
    private int currentViewType;

    // 修改构造方法,传入当前要使用的视图类型
    public BookRecyclerViewAdapter(Context context, int currentViewType) { 
        this.context = context;
        this.currentViewType = currentViewType;
    }
    // ... 其他原有代码
}

步骤2:重写getItemViewType方法

这个方法告诉RecyclerView每个位置对应的视图类型,因为你是在不同Activity中使用整个列表的同一种布局,所以直接返回我们传入的currentViewType即可:

@Override
public int getItemViewType(int position) {
    return currentViewType;
}

步骤3:修改ViewHolder结构

因为现在有两种布局,需要分别创建对应的ViewHolder。保留你原来的可展开CardView逻辑,重命名ViewHolder让代码更清晰,再新增一个对应新布局的ViewHolder:

// 原来的可展开CardView对应的ViewHolder,重命名更清晰
public class ExpandableCardViewHolder extends RecyclerView.ViewHolder { 
    private CardView parent; 
    private ImageView imgBook; 
    private TextView txtName; 
    private ImageView downArrow, upArrow; 
    private RelativeLayout expanded, collapsed; 
    private TextView txtAuthor, txtDesc; 

    public ExpandableCardViewHolder(@NonNull View itemView) { 
        super(itemView); 
        parent = itemView.findViewById(R.id.parent); // 注意:这里原来的引号要去掉,直接用R.id.xxx
        imgBook = itemView.findViewById(R.id.imgBook); 
        txtName = itemView.findViewById(R.id.txtBookName); 
        downArrow = itemView.findViewById(R.id.btnDownArrow); 
        upArrow = itemView.findViewById(R.id.btnUpArrow); 
        expanded = itemView.findViewById(R.id.expandedRellayout); 
        collapsed = itemView.findViewById(R.id.collapsedRelLayout); 
        txtAuthor = itemView.findViewById(R.id.txtAuthor); 
        txtDesc = itemView.findViewById(R.id.txtShortDesc); 

        // 原有点击事件逻辑保留
        downArrow.setOnClickListener(v -> { 
            Book book = books.get(getAdapterPosition()); 
            book.setExpanded(!book.isExpanded()); 
            notifyItemChanged(getAdapterPosition()); 
        }); 

        upArrow.setOnClickListener(v -> { 
            Book book = books.get(getAdapterPosition()); 
            book.setExpanded(!book.isExpanded()); 
            notifyItemChanged(getAdapterPosition()); 
        }); 
    } 
}

// 新布局对应的ViewHolder
public class OtherLayoutViewHolder extends RecyclerView.ViewHolder {
    // 根据你的新布局定义控件,示例如下:
    private TextView tvBookTitle;
    private ImageView ivCover;

    public OtherLayoutViewHolder(@NonNull View itemView) {
        super(itemView);
        tvBookTitle = itemView.findViewById(R.id.tv_book_title);
        ivCover = itemView.findViewById(R.id.iv_cover);

        // 新布局的点击事件逻辑,比如跳转到详情页
        itemView.setOnClickListener(v -> {
            Book book = books.get(getAdapterPosition());
            Intent intent = new Intent(context, BookActivity.class);
            intent.putExtra("BOOK_ID_KEY", book.getId());
            context.startActivity(intent);
        });
    }
}

步骤4:修改onCreateViewHolder方法

根据不同的视图类型加载对应的布局文件,并返回对应的ViewHolder:

@NonNull 
@Override 
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    if (viewType == VIEW_TYPE_EXPANDABLE_CARD) {
        View view = inflater.inflate(R.layout.list_item_book, parent, false); // 去掉原来的引号
        return new ExpandableCardViewHolder(view);
    } else {
        // 加载你的新布局文件
        View view = inflater.inflate(R.layout.your_new_book_layout, parent, false);
        return new OtherLayoutViewHolder(view);
    }
}

步骤5:修改onBindViewHolder方法

根据不同的ViewHolder类型,绑定对应的数据和逻辑:

@Override 
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { 
    Book book = books.get(position);
    if (holder instanceof ExpandableCardViewHolder) {
        // 原来的可展开CardView绑定逻辑保留
        ExpandableCardViewHolder cardHolder = (ExpandableCardViewHolder) holder;
        cardHolder.txtName.setText(book.getName()); 
        cardHolder.txtAuthor.setText(book.getAuthor()); 
        cardHolder.txtDesc.setText(book.getShortDesc()); 

        Glide.with(context) 
            .asBitmap() 
            .load(book.getImgUrl()) 
            .into(cardHolder.imgBook); 

        cardHolder.parent.setOnClickListener(v -> { 
            Intent intent = new Intent(context, BookActivity.class); 
            intent.putExtra("BOOK_ID_KEY", book.getId()); 
            context.startActivity(intent); 
        }); 

        if (book.isExpanded()) { 
            TransitionManager.beginDelayedTransition(cardHolder.parent); 
            cardHolder.expanded.setVisibility(View.VISIBLE); 
            cardHolder.downArrow.setVisibility(View.GONE); 
        } else { 
            TransitionManager.beginDelayedTransition(cardHolder.parent); 
            cardHolder.expanded.setVisibility(View.GONE); 
            cardHolder.downArrow.setVisibility(View.VISIBLE); 
        }
    } else if (holder instanceof OtherLayoutViewHolder) {
        // 新布局的绑定逻辑
        OtherLayoutViewHolder otherHolder = (OtherLayoutViewHolder) holder;
        otherHolder.tvBookTitle.setText(book.getName());
        Glide.with(context)
             .load(book.getImgUrl())
             .into(otherHolder.ivCover);
        // 其他新布局需要的绑定操作
    }
}

如何在不同Activity中使用

  • 在原来使用可展开CardView的Activity中:
BookRecyclerViewAdapter adapter = new BookRecyclerViewAdapter(this, BookRecyclerViewAdapter.VIEW_TYPE_EXPANDABLE_CARD);
// 设置数据等操作
recyclerView.setAdapter(adapter);
  • 在新的Activity中使用另一种布局:
BookRecyclerViewAdapter adapter = new BookRecyclerViewAdapter(this, BookRecyclerViewAdapter.VIEW_TYPE_OTHER_LAYOUT);
// 设置数据等操作
recyclerView.setAdapter(adapter);

这样就完美复用了同一个Adapter,不需要额外新建啦!另外提个小细节:你原来代码里findViewById和inflate中的"R.id.xxx"是错误的,要去掉引号直接用R.id.xxx哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:57:31