如何根据Spinner选择获取Firebase实时数据库的键值(课程代码)
问题:Spinner选中课程时显示对应Firebase课程代码到TextView
我在Firebase Realtime Database中存储了课程详情,已经把课程名称加载到Spinner里让用户选择。现在想实现用户选中Spinner里的课程时,把对应的课程代码(也就是Firebase里的键)显示到Android的TextView中。
我用fetchDataForSpinner()方法加载课程名称到Spinner,但不知道怎么根据用户选择获取对应的课程代码。之前尝试用getKey()方法,只能拿到最后一个课程的键。
Firebase数据结构
Courses Faculty of IT Year 01 Semester 01 BMG11073: "Entrepreneurship & Growing Business" IT11013: "IT & Computing Fundamentals" IT11023: "Programming Fundamentals" IT11033: "Statistics" IT11041: "Psychology" IT11052: "Leadership and Communication Skills"
现有代码
public void fetchDataForSpinner() { spinnerReference = FirebaseDatabase.getInstance().getReference("Courses"); spinnerReference.child(faculty).child(semester).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if(snapshot.exists()) { for (DataSnapshot item : snapshot.getChildren()) { spinnerCourseList.add(item.getValue().toString()); // String courseCodeFromKey = snapshot.getKey(); // editTextForCourseCode.setText(courseCodeFromKey); } adapterCourse.notifyDataSetChanged(); } else{ Toast.makeText(AddGradesMain.this, "Course Not Added!", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(AddGradesMain.this, "Course not added to the database!", Toast.LENGTH_SHORT).show(); } }); }
解决方案
1. 创建Course类绑定代码和名称
首先需要一个类来关联课程代码(Firebase节点的键)和课程名称(节点的值),这样Spinner能同时保存两者的关联关系:
public class Course { private String code; private String name; // 带参构造函数 public Course(String code, String name) { this.code = code; this.name = name; } // 空构造函数必须有,Firebase序列化/反序列化需要 public Course() {} // getter方法 public String getCode() { return code; } public String getName() { return name; } // 重写toString,Spinner会显示这个方法返回的文本(也就是课程名称) @Override public String toString() { return name; } }
2. 修改fetchDataForSpinner方法,存储完整Course对象
把原来只存课程名称的列表改成存储Course对象,这样每个条目都包含代码和名称:
// 把spinnerCourseList的类型改为List<Course> private List<Course> spinnerCourseList = new ArrayList<>(); public void fetchDataForSpinner() { spinnerReference = FirebaseDatabase.getInstance().getReference("Courses"); spinnerReference.child(faculty).child(semester).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if(snapshot.exists()) { // 先清空列表,防止重复加载数据 spinnerCourseList.clear(); for (DataSnapshot item : snapshot.getChildren()) { // 获取单个课程的键(代码)和值(名称) String courseCode = item.getKey(); String courseName = item.getValue().toString(); // 添加Course对象到列表 spinnerCourseList.add(new Course(courseCode, courseName)); } adapterCourse.notifyDataSetChanged(); } else { Toast.makeText(AddGradesMain.this, "未找到课程!", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(AddGradesMain.this, "数据库加载失败!", Toast.LENGTH_SHORT).show(); } }); }
3. 设置Spinner选择监听器,获取选中课程的代码
在初始化Spinner的位置(比如Activity的onCreate方法),添加选择监听器,当用户选中课程时,直接从Course对象中取出代码并显示到TextView:
// 初始化Spinner和适配器 Spinner courseSpinner = findViewById(R.id.your_spinner_id); adapterCourse = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerCourseList); adapterCourse.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); courseSpinner.setAdapter(adapterCourse); // 添加选择事件监听器 courseSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // 获取选中的Course对象 Course selectedCourse = spinnerCourseList.get(position); // 将课程代码设置到TextView editTextForCourseCode.setText(selectedCourse.getCode()); } @Override public void onNothingSelected(AdapterView<?> parent) { // 未选中任何项时的处理(可选) editTextForCourseCode.setText(""); } });
原问题原因说明
你之前用snapshot.getKey()获取的是整个Year 01 Semester 01节点的键,而不是单个课程的键。要获取每个课程的键,必须在循环中使用item.getKey()(item是每个课程节点的快照)。同时,只存储课程名称的话,无法建立名称和代码的对应关系,所以需要用自定义类来绑定两者。
内容的提问来源于stack exchange,提问作者Thadhasneem Nooriya
相关产品推荐
相关产品推荐

