Java实现RecyclerView点击SQLite数据跳转Activity传值失败排查
问题根因
代码存在3个核心逻辑错误,导致点击item无法正确传值:
- 初始化顺序错误:
onCreate中先创建Adapter实例传入listener,之后才调用setOnClickListener()初始化listener,Adapter持有的listener始终为null,Activity中写的传值逻辑根本不会触发 - 点击事件冲突:Adapter的
onBindViewHolder方法里给CardView单独写了跳转逻辑,直接启动目标Activity,既没有走自定义接口回调,也没有往Intent里塞任何参数,跳转后自然拿不到数据 - 监听绑定无效:ViewHolder构造函数里仅创建了OnClickListener实例,没有把监听器设置给任何控件,接口回调没有触发入口
修复方案
- 调整Activity中代码执行顺序:先初始化点击监听器,再创建Adapter、绑定到RecyclerView
- 删除Adapter中
onBindViewHolder里写的无效CardView跳转逻辑,点击统一走接口回调处理 - 在ViewHolder构造方法中给CardView绑定点击监听,触发回调时传递当前item的正确位置
- 补全数据加载后的列表刷新逻辑、目标Activity的取参逻辑
修正后完整代码
列表页Activity代码
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_staff_home); DB = new mainTextDBHelper(this); recyclerView = findViewById(R.id.recyclerview); Title = new ArrayList<>(); description = new ArrayList<>(); radiogroup = new ArrayList<>(); // 先初始化监听器,再传入Adapter setOnClickListner(); adapter = new recyclerviewAdapter(this,Title,description,radiogroup,listener); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(this)); displaydata(); } private void setOnClickListner() { listener = new recyclerviewAdapter.RecyclerViewClickListener() { @Override public void onClick(View v, int position) { // 用Activity实例做上下文,不要用applicationContext启动页面 Intent intent = new Intent(staff_home.this, cardviewclickon.class); // 把需要传递的所有字段都塞入Intent intent.putExtra("Title", Title.get(position)); intent.putExtra("description", description.get(position)); intent.putExtra("severity", radiogroup.get(position)); startActivity(intent); } }; } private void displaydata() { Cursor cursor = DB.getdata(); if(cursor.getCount() == 0){ Toast.makeText(staff_home.this,"No Entry Exists", Toast.LENGTH_SHORT).show(); return; } while(cursor.moveToNext()) { Title.add(cursor.getString(1)); description.add(cursor.getString(2)); radiogroup.add(cursor.getString(3)); } // 数据加载完成后通知列表刷新,避免首次进入空白 adapter.notifyDataSetChanged(); }
RecyclerView Adapter代码
public class recyclerviewAdapter extends RecyclerView.Adapter<recyclerviewAdapter.MyViewHolder>{ private Context context; private ArrayList Title_id,description_id,radiogroup_id; private RecyclerViewClickListener listener; public recyclerviewAdapter(Context context, ArrayList title_id, ArrayList description_id, ArrayList radiogroup_id,RecyclerViewClickListener listener) { this.context = context; Title_id = title_id; this.description_id = description_id; this.radiogroup_id = radiogroup_id; this.listener = listener; } @NonNull @Override public recyclerviewAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(context).inflate(R.layout.userentry,parent,false); return new MyViewHolder(v); } @Override public void onBindViewHolder(@NonNull recyclerviewAdapter.MyViewHolder holder, int position) { holder.Title_id.setText(String.valueOf(Title_id.get(position))); holder.description_id.setText(String.valueOf(description_id.get(position))); holder.radiogroup_id.setText(String.valueOf(radiogroup_id.get(position))); // 删除此处原有的CardView无效跳转逻辑 } @Override public int getItemCount() { return Title_id.size(); } public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ TextView Title_id,description_id,radiogroup_id; CardView cardView; public MyViewHolder(@NonNull View itemView) { super(itemView); Title_id = itemView.findViewById(R.id.textTitle); description_id = itemView.findViewById(R.id.textdescription); radiogroup_id = itemView.findViewById(R.id.textsrverity); cardView = itemView.findViewById(R.id.card); // 给CardView绑定点击监听,不要仅创建实例不绑定 cardView.setOnClickListener(this); } @Override public void onClick(View view) { // 传递当前item的真实位置给回调 listener.onClick(view, getBindingAdapterPosition()); } } public interface RecyclerViewClickListener{ void onClick(View v,int position); } }
目标详情页取参示例
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cardviewclickon); // 取出Intent传递的参数 String title = getIntent().getStringExtra("Title"); String desc = getIntent().getStringExtra("description"); String severity = getIntent().getStringExtra("severity"); // 后续将数据绑定到页面控件即可 }
优化建议
- 给集合指定泛型,例如
ArrayList<String> Title,避免无泛型带来的类型转换异常 - 类名遵循大驼峰命名规范,例如将
recyclerviewAdapter改为RecyclerViewAdapter、cardviewclickon改为CardDetailActivity,提升代码可维护性 - 数据库操作不要放在主线程执行,数据量较大时会造成页面卡顿,建议配合协程或RxJava做异步处理
内容的提问来源于stack exchange,提问作者LucK
相关产品推荐
相关产品推荐

