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

如何在同一RecyclerView Adapter中适配不同类型的ArrayList?

解决同一RecyclerView Adapter适配多种ArrayList的问题

嘿,这个场景太常见了!我之前帮好几个开发者解决过类似的问题——同一个Adapter要给多个页面的RecyclerView用,还得适配不同类型的数据源,核心就是让getItemCount()能动态返回当前数据源的长度,同时保证数据绑定的灵活性。下面给你两个实用的方案,你可以根据自己的代码风格选:

方案一:泛型+数据绑定回调(推荐,扩展性强)

这个方案通过泛型让Adapter支持任意数据类型,再用一个回调接口让每个页面自己处理数据到View的绑定逻辑,完美适配你的需求。

第一步:编写泛型Adapter

public class CommonRecyclerAdapter<T> extends RecyclerView.Adapter<CommonRecyclerAdapter.CommonViewHolder> {
    private List<T> mDataSource;
    private LayoutInflater mInflater;
    private OnBindDataListener<T> mBindListener;

    // 定义数据绑定的回调接口,让外部实现具体的绑定逻辑
    public interface OnBindDataListener<T> {
        void onBindData(T item, CommonViewHolder holder);
    }

    // 构造方法:传入上下文、数据源、绑定回调
    public CommonRecyclerAdapter(Context context, List<T> dataSource, OnBindDataListener<T> bindListener) {
        mInflater = LayoutInflater.from(context);
        mDataSource = dataSource;
        mBindListener = bindListener;
    }

    // 更新数据源的方法,调用后会刷新列表
    public void updateDataSource(List<T> newData) {
        if (mDataSource != null) {
            mDataSource.clear();
            mDataSource.addAll(newData);
        } else {
            mDataSource = newData;
        }
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public CommonViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // 加载你的通用item布局
        View itemView = mInflater.inflate(R.layout.your_common_item_layout, parent, false);
        return new CommonViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull CommonViewHolder holder, int position) {
        // 拿到当前位置的数据,交给外部回调处理绑定
        T item = mDataSource.get(position);
        mBindListener.onBindData(item, holder);
    }

    @Override
    public int getItemCount() {
        // 直接返回当前数据源的长度,空的话返回0避免空指针
        return mDataSource != null ? mDataSource.size() : 0;
    }

    // 通用ViewHolder,这里定义你item布局里的所有View
    public static class CommonViewHolder extends RecyclerView.ViewHolder {
        public TextView tvContent;
        public ImageView ivIcon;
        // 可以根据你的布局添加更多View

        public CommonViewHolder(@NonNull View itemView) {
            super(itemView);
            tvContent = itemView.findViewById(R.id.tv_content);
            ivIcon = itemView.findViewById(R.id.iv_icon);
        }
    }
}

第二步:在各个Activity中使用

比如第一个Activity用User类型的列表:

// 初始化你的用户数据列表
List<User> userList = new ArrayList<>();
// 填充数据...

// 创建Adapter,传入User类型和对应的绑定逻辑
CommonRecyclerAdapter<User> userAdapter = new CommonRecyclerAdapter<>(this, userList, (item, holder) -> {
    holder.tvContent.setText(item.getUserName());
    holder.ivIcon.setImageResource(item.getAvatarResId());
});
// 设置给RecyclerView
recyclerView.setAdapter(userAdapter);

第二个Activity用Product类型的列表:

List<Product> productList = new ArrayList<>();
// 填充数据...

CommonRecyclerAdapter<Product> productAdapter = new CommonRecyclerAdapter<>(this, productList, (item, holder) -> {
    holder.tvContent.setText(item.getProductName());
    holder.ivIcon.setImageResource(item.getProductImageResId());
});
recyclerView.setAdapter(productAdapter);

这样getItemCount()会自动根据当前泛型列表的长度返回正确值,而且每个页面可以自定义数据绑定逻辑,完全不冲突。

方案二:多数据源+类型标记(适合不想用泛型的场景)

如果你的项目里泛型用得不多,也可以给Adapter维护多个数据源,用一个标记变量区分当前使用的类型,在getItemCount()和数据绑定的时候做判断。

编写Adapter

public class CommonRecyclerAdapter extends RecyclerView.Adapter<CommonRecyclerAdapter.CommonViewHolder> {
    private List<User> mUserList;
    private List<Product> mProductList;
    private List<Order> mOrderList;
    private int mCurrentType;
    private LayoutInflater mInflater;

    // 定义类型常量
    public static final int TYPE_USER = 0;
    public static final int TYPE_PRODUCT = 1;
    public static final int TYPE_ORDER = 2;

    public CommonRecyclerAdapter(Context context, int currentType) {
        mInflater = LayoutInflater.from(context);
        mCurrentType = currentType;
    }

    // 分别设置不同类型的数据源
    public void setUserList(List<User> userList) {
        mUserList = userList;
        notifyDataSetChanged();
    }

    public void setProductList(List<Product> productList) {
        mProductList = productList;
        notifyDataSetChanged();
    }

    public void setOrderList(List<Order> orderList) {
        mOrderList = orderList;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        // 根据当前类型返回对应列表的长度
        switch (mCurrentType) {
            case TYPE_USER:
                return mUserList != null ? mUserList.size() : 0;
            case TYPE_PRODUCT:
                return mProductList != null ? mProductList.size() : 0;
            case TYPE_ORDER:
                return mOrderList != null ? mOrderList.size() : 0;
            default:
                return 0;
        }
    }

    @Override
    public void onBindViewHolder(@NonNull CommonViewHolder holder, int position) {
        // 根据类型绑定对应的数据
        switch (mCurrentType) {
            case TYPE_USER:
                User user = mUserList.get(position);
                holder.tvContent.setText(user.getUserName());
                holder.ivIcon.setImageResource(user.getAvatarResId());
                break;
            case TYPE_PRODUCT:
                Product product = mProductList.get(position);
                holder.tvContent.setText(product.getProductName());
                holder.ivIcon.setImageResource(product.getProductImageResId());
                break;
            case TYPE_ORDER:
                Order order = mOrderList.get(position);
                holder.tvContent.setText(order.getOrderNumber());
                break;
        }
    }

    // ViewHolder和onCreateViewHolder和方案一一致
    public static class CommonViewHolder extends RecyclerView.ViewHolder {
        public TextView tvContent;
        public ImageView ivIcon;

        public CommonViewHolder(@NonNull View itemView) {
            super(itemView);
            tvContent = itemView.findViewById(R.id.tv_content);
            ivIcon = itemView.findViewById(R.id.iv_icon);
        }
    }
}

在Activity中使用

// 用户列表页面
CommonRecyclerAdapter adapter = new CommonRecyclerAdapter(this, CommonRecyclerAdapter.TYPE_USER);
adapter.setUserList(userList);
recyclerView.setAdapter(adapter);

这个方案的缺点是以后如果要新增数据类型,就得修改Adapter的代码,扩展性不如方案一,所以更推荐第一种泛型的方式。

额外注意事项

  • 如果你的数据量很大,建议用DiffUtil来优化数据源更新,避免全量刷新RecyclerView,提升性能。
  • 确保在主线程调用notifyDataSetChanged()或者updateDataSource()方法,避免UI线程异常。
  • ViewHolder里的View一定要正确初始化,避免空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:24:31