如何通过泛型在BaseAdapter基类内部获取继承它的子类?
嘿,这个问题我熟!咱们可以通过让BaseAdapter成为泛型类来彻底解决每次要指定具体子类的麻烦,既能保证类型安全,又能让基类提供通用的刷新逻辑。下面一步步来实现:
第一步:重构BaseAdapter为泛型基类
首先把BaseAdapter改成泛型类,绑定数据类型和ViewHolder类型,同时实现通用的refreshData方法——子类可以直接用,也能按需重写扩展:
import android.view.ViewGroup; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; public abstract class BaseAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> { protected List<T> mData; // 构造方法初始化数据 public BaseAdapter(List<T> data) { this.mData = data != null ? data : new ArrayList<>(); } // 通用刷新方法,子类可重写 public void refreshData(List<T> newData) { mData.clear(); mData.addAll(newData); notifyDataSetChanged(); // 也可以替换为DiffUtil实现局部刷新,这里先简化 } // 子类必须实现的核心抽象方法 @Override public abstract VH onCreateViewHolder(ViewGroup parent, int viewType); @Override public abstract void onBindViewHolder(VH holder, int position); @Override public int getItemCount() { return mData.size(); } }
第二步:子类继承泛型基类
比如你的TopicAdapter,继承的时候只需要指定对应的数据类型和ViewHolder类型就行,完全不用重复写刷新逻辑(除非你需要自定义):
public class TopicAdapter extends BaseAdapter<Topic, TopicViewHolder> { public TopicAdapter(List<Topic> data) { super(data); } @Override public TopicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 这里写你的ViewHolder创建逻辑,比如加载布局 return new TopicViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_topic, parent, false)); } @Override public void onBindViewHolder(TopicViewHolder holder, int position) { // 绑定数据到ViewHolder,直接用mData获取数据 Topic topic = mData.get(position); holder.tvTitle.setText(topic.getTitle()); // ...其他绑定逻辑 } // 如果需要自定义刷新逻辑,重写refreshData即可 @Override public void refreshData(List<Topic> newData) { super.refreshData(newData); // 比如添加额外的状态更新、动画等 } }
第三步:优化外部调用代码
现在你再也不用判断具体是哪个子类了,只需要判断是否是BaseAdapter的实例,通过泛型安全转换后直接调用refreshData:
方式1:直接转换调用
RecyclerView.Adapter adapter = mRecyclerView.getAdapter(); if (adapter instanceof BaseAdapter) { // 这里指定数据类型,比如Topic,就能直接调用refreshData ((BaseAdapter<Topic, ?>) adapter).refreshData(topicDetails); } else { // 如果Adapter不存在,直接创建对应的BaseAdapter子类 BaseAdapter<Topic, TopicViewHolder> newAdapter = new TopicAdapter(new ArrayList<>()); newAdapter.refreshData(topicDetails); mRecyclerView.setAdapter(newAdapter); }
方式2:封装泛型工具方法(更优雅)
如果不想每次都写强转,可以封装一个工具方法,简化调用:
@SuppressWarnings("unchecked") private <T, VH extends RecyclerView.ViewHolder> BaseAdapter<T, VH> getBaseAdapter(RecyclerView recyclerView) { RecyclerView.Adapter adapter = recyclerView.getAdapter(); return adapter instanceof BaseAdapter ? (BaseAdapter<T, VH>) adapter : null; }
然后调用就超简洁:
BaseAdapter<Topic, TopicViewHolder> adapter = getBaseAdapter(mRecyclerView); if (adapter != null) { adapter.refreshData(topicDetails); } else { adapter = new TopicAdapter(new ArrayList<>()); adapter.refreshData(topicDetails); mRecyclerView.setAdapter(adapter); }
核心思路
通过泛型让BaseAdapter和子类绑定具体的数据类型,既避免了无意义的强转,又让基类能提供通用的刷新逻辑——所有继承BaseAdapter的子类都能直接复用这个能力,你再也不用在代码里写死具体的子类名称啦!
内容的提问来源于stack exchange,提问作者bycfly
相关产品推荐
相关产品推荐

