Android RecyclerView自定义Adapter类应当选择哪个父类?
答案
你当前使用RecyclerView作为列表承载容器,因此自定义Adapter的父类必须选择androidx.recyclerview.widget.RecyclerView.Adapter,这个选择和你列表项内部用CardView、TextView、EditText这些控件没有关系,Adapter父类只和你选用的列表容器类型匹配。
注意:不要使用ListView配套的
BaseAdapter/ArrayAdapter等父类,这些类和RecyclerView完全不兼容,无法设置给RecyclerView使用。
实现步骤参考
1. 修正数据模型类命名
Java类名遵循大驼峰命名规范,你原来写的cellProperties建议改名为CellProperties,对应每行三个字段的基础结构参考:
public class CellProperties { private int index; // 序号 private String taskName; // 任务名称 private String totalTime; // 累计耗时 public CellProperties(int index, String taskName, String totalTime) { this.index = index; this.taskName = taskName; this.totalTime = totalTime; } // 补全所有字段的getter、setter方法 public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public String getTaskName() { return taskName; } public void setTaskName(String taskName) { this.taskName = taskName; } public String getTotalTime() { return totalTime; } public void setTotalTime(String totalTime) { this.totalTime = totalTime; } }
2. 实现自定义Adapter与配套ViewHolder
你需要先写一个继承RecyclerView.ViewHolder的视图持有类,用来绑定单行布局的三个控件,再实现Adapter的核心方法,基础参考代码如下:
public class TimeTableAdapter extends RecyclerView.Adapter<TimeTableAdapter.TaskViewHolder> { private final List<CellProperties> mDataList; public TimeTableAdapter(List<CellProperties> dataList) { this.mDataList = dataList; } @NonNull @Override public TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // 加载你写的单行CardView布局 View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.替换成你单行布局的文件名, parent, false); return new TaskViewHolder(itemView); } @Override public void onBindViewHolder(@NonNull TaskViewHolder holder, int position) { CellProperties item = mDataList.get(position); holder.tvIndex.setText(item.getIndex() + "."); holder.etTaskName.setText(item.getTaskName()); holder.etTotalTime.setText(item.getTotalTime()); // 必须给EditText加文本监听,把用户输入同步回数据源,否则列表滑动时会出现输入内容错乱、丢失的问题 holder.etTaskName.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { item.setTaskName(s.toString()); } @Override public void afterTextChanged(Editable s) {} }); // 累计耗时输入框同理加文本监听同步数据 } @Override public int getItemCount() { return mDataList == null ? 0 : mDataList.size(); } // 自定义ViewHolder,持有单行布局内的所有控件 static class TaskViewHolder extends RecyclerView.ViewHolder { final TextView tvIndex; final EditText etTaskName; final EditText etTotalTime; public TaskViewHolder(@NonNull View itemView) { super(itemView); tvIndex = itemView.findViewById(R.id.index); etTaskName = itemView.findViewById(R.id.taskName); etTotalTime = itemView.findViewById(R.id.totalHours); } } }
3. 补全Activity里的RecyclerView初始化逻辑
你当前的Activity代码只声明了RecyclerView、Adapter、LayoutManager,没有完成初始化配置,补充后参考如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.time_table); recyclerView = findViewById(R.id.list); // 必须给RecyclerView设置LayoutManager,否则不会显示任何列表内容 layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); List<CellProperties> cells = new ArrayList<>(); // 可以先添加一条默认测试数据 cells.add(new CellProperties(1, "", "")); // 初始化Adapter并设置给RecyclerView adapter = new TimeTableAdapter(cells); recyclerView.setAdapter(adapter); findViewById(R.id.add).setOnClickListener(view -> { // 点击加号新增行逻辑:给数据源加新项,通知Adapter刷新 int newIndex = cells.size() + 1; cells.add(new CellProperties(newIndex, "", "")); adapter.notifyItemInserted(cells.size() - 1); }); }
内容的提问来源于stack exchange,提问作者Parth Gupta
相关产品推荐
相关产品推荐

