Android Studio SQLite查询课程详情始终显示最后一条记录问题
问题根因
你的判断完全正确,核心问题出在静态控件引用和数据传递逻辑的错误上,具体有3个直接触发bug的点:
- 你在
CourseAdapter中通过CourseViewHolder.courseTitle(静态类引用)获取选中课程名,RecyclerView完成所有条目绑定后,这个静态引用永远指向最后一个绑定的列表项,无论点击哪个条目,取到的都是最后一门课的标题,因此数据库查询永远返回最后一条记录,仅当数据库只有1条数据时会碰巧正常。 - 你在
onBindViewHolder中提前读取str1/str2/str3三个值的时机错误,这三个值在条目绑定时就被固定为当前静态控件的内容,不是用户点击时对应条目的真实值;且你虽然把这三个值塞进了Intent,但CourseDetailActivity完全没有读取Intent传参,反而直接调用依赖静态控件的错误查询方法,传递链路完全断裂。 - 原有
getCourseDetails方法设计缺陷明显:使用LIKE模糊匹配容易因重名课程返回多条结果,且把所有查询结果无结构塞入字符串列表,直接按下标取值的逻辑在返回多条数据时必然取错字段。
修复步骤
1. 调整列表点击传参逻辑
修改CourseAdapter的onBindViewHolder方法,删除错误的静态控件取值逻辑,点击时直接传递当前条目的唯一课程ID(主键,不会重复,比传标题可靠):
@Override public void onBindViewHolder(CourseViewHolder holder, int position) { final Courses courses = listCourses.get(position); holder.courseTitle.setText(courses.getCourseTitle()); holder.courseStart.setText(courses.getCourseStart()); holder.courseEnd.setText(courses.getCourseEnd()); // 删除原来的str1/str2/str3静态取值代码 holder.viewCourse.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(context, CourseDetailActivity.class); // 传递课程主键ID,唯一标识选中的课程 intent.putExtra("course_id_key", courses.getId()); context.startActivity(intent); } }); // 其余编辑、删除逻辑保持不变 // ... }
注意:把
CourseViewHolder类中所有声明为static的View控件(courseTitle、courseStart等)全部改为普通成员变量,静态View引用是RecyclerView数据错乱的常见诱因。
2. 重构数据库查询方法
删除原有无参的getCourseDetails方法,改为接收课程ID作为参数,精确查询单条课程,直接返回实体类避免无结构列表的取值错误:
public Courses getCourseById(int courseId) { SQLiteDatabase db = this.getReadableDatabase(); // 使用?占位符避免SQL注入,主键精确匹配只返回单条记录 Cursor cursor = db.rawQuery( "SELECT * FROM " + TABLE_COURSES + " WHERE " + COURSE_ID + " = ?", new String[]{String.valueOf(courseId)} ); Courses targetCourse = null; if (cursor.moveToFirst()) { targetCourse = new Courses( cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), cursor.getString(5), cursor.getString(6), cursor.getString(7), cursor.getString(8) ); } cursor.close(); db.close(); return targetCourse; }
3. 调整详情页数据加载逻辑
修改CourseDetailActivity的onCreate方法,先从Intent读取传递的课程ID,再调用新的查询方法获取课程数据,完成控件赋值:
@Override protected void onCreate(Bundle savedInstanceState) { this.getSupportActionBar().setDisplayHomeAsUpEnabled(true); super.onCreate(savedInstanceState); setContentView(R.layout.activity_course_details); title = (TextView) findViewById(R.id.course_title); start = (TextView) findViewById(R.id.course_start); end = (TextView) findViewById(R.id.course_end); status = (TextView) findViewById(R.id.course_status); name = (TextView) findViewById(R.id.instructor_name); phone = (TextView) findViewById(R.id.instructor_phone); email = (TextView) findViewById(R.id.instructor_email); term = (TextView) findViewById(R.id.term); // 读取Intent传参,增加容错判断 int courseId = getIntent().getIntExtra("course_id_key", -1); if (courseId == -1) { Toast.makeText(this, "课程参数异常", Toast.LENGTH_SHORT).show(); finish(); return; } TermTrackerDatabase db = new TermTrackerDatabase(getApplicationContext()); Courses selectedCourse = db.getCourseById(courseId); if (selectedCourse == null) { Toast.makeText(this, "查询课程信息失败", Toast.LENGTH_SHORT).show(); finish(); return; } // 给控件赋值 title.setText(selectedCourse.getCourseTitle()); start.setText(selectedCourse.getCourseStart()); end.setText(selectedCourse.getCourseEnd()); status.setText(selectedCourse.getCourseStatus()); name.setText(selectedCourse.getInstructorName()); phone.setText(selectedCourse.getInstructorPhone()); email.setText(selectedCourse.getInstructorEmail()); term.setText(selectedCourse.getAssociatedTerm()); }
改完之后无论点击哪个课程,都会通过唯一ID精确匹配对应记录,不会再出现永远显示最后一条的问题。
内容的提问来源于stack exchange,提问作者5150 Design
相关产品推荐
相关产品推荐

