基于Spinner选择的血型与城市条件从数据库查询数据并展示至ListView
没问题,我来帮你一步步实现这个功能!下面是具体的操作步骤,分模块说明,你可以跟着来:
1. 编写数据库查询方法
首先得在你的数据库Helper类里添加一个能根据血型和城市过滤数据的方法,这样才能精准获取符合条件的人员信息。这里提供两种实现方式,你可以根据自己的需求选:
方式一:返回Cursor(适合用SimpleCursorAdapter)
public class DBHelper extends SQLiteOpenHelper { // ... 其他已有的代码(构造方法、onCreate、onUpgrade等) public Cursor getFilteredPersons(String bloodGroup, String city) { SQLiteDatabase db = this.getReadableDatabase(); // 用参数绑定避免SQL注入,一定要注意! String query = "SELECT * FROM persons WHERE blood_group = ? AND city = ?"; return db.rawQuery(query, new String[]{bloodGroup, city}); } }
方式二:返回实体类列表(更直观,推荐)
先定义一个Person实体类来封装人员信息:
public class Person { private int id; private String name; private String bloodGroup; private String city; // 其他你需要的字段(比如联系方式等) // Getter和Setter方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getBloodGroup() { return bloodGroup; } public void setBloodGroup(String bloodGroup) { this.bloodGroup = bloodGroup; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
然后在DBHelper里添加返回列表的方法:
public List<Person> getFilteredPersonsList(String bloodGroup, String city) { List<Person> personList = new ArrayList<>(); Cursor cursor = getFilteredPersons(bloodGroup, city); if (cursor.moveToFirst()) { do { Person person = new Person(); person.setId(cursor.getInt(cursor.getColumnIndexOrThrow("id"))); person.setName(cursor.getString(cursor.getColumnIndexOrThrow("name"))); person.setBloodGroup(cursor.getString(cursor.getColumnIndexOrThrow("blood_group"))); person.setCity(cursor.getString(cursor.getColumnIndexOrThrow("city"))); // 给其他字段赋值 personList.add(person); } while (cursor.moveToNext()); } cursor.close(); // 记得关闭Cursor,避免内存泄漏 return personList; }
2. 初始化两个Spinner
接下来在你的Activity/Fragment里初始化Spinner,设置选项数据源:
// 初始化血型Spinner(选项在Java里定义) Spinner bloodGroupSpinner = findViewById(R.id.spinner_blood_group); String[] bloodGroupOptions = {"A+ve", "A-ve", "B+ve", "B-ve", "O+ve", "O-ve", "AB+ve", "AB-ve"}; ArrayAdapter<String> bloodGroupAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, bloodGroupOptions); bloodGroupAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); bloodGroupSpinner.setAdapter(bloodGroupAdapter); // 初始化城市Spinner Spinner citySpinner = findViewById(R.id.spinner_city); String[] cityOptions = {"Delhi", "Gurgaon", "Noida", "Mumbai"}; // 这里可以换成从数据库加载的动态数据 ArrayAdapter<String> cityAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, cityOptions); cityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); citySpinner.setAdapter(cityAdapter);
3. 处理搜索按钮的点击事件
给搜索按钮添加点击监听器,获取选中的血型和城市,查询数据库后把结果绑定到ListView:
Button searchBtn = findViewById(R.id.btn_search); ListView personListView = findViewById(R.id.list_view_persons); DBHelper dbHelper = new DBHelper(this); searchBtn.setOnClickListener(v -> { // 获取Spinner选中的值 String selectedBloodGroup = bloodGroupSpinner.getSelectedItem().toString(); String selectedCity = citySpinner.getSelectedItem().toString(); // 查询符合条件的人员 List<Person> filteredPersons = dbHelper.getFilteredPersonsList(selectedBloodGroup, selectedCity); // 给ListView设置适配器 PersonAdapter adapter = new PersonAdapter(this, filteredPersons); personListView.setAdapter(adapter); // 如果没有匹配数据,给用户提示 if (filteredPersons.isEmpty()) { Toast.makeText(this, "没有找到符合条件的人员信息", Toast.LENGTH_SHORT).show(); } });
4. 自定义ListView适配器
为了更好地展示人员详情,需要写一个自定义的Adapter。先创建列表项的布局list_item_person.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:textStyle="bold"/> <TextView android:id="@+id/tv_blood_group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:layout_marginTop="4dp"/> <TextView android:id="@+id/tv_city" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:layout_marginTop="4dp"/> <!-- 可以添加更多展示字段,比如联系方式等 --> </LinearLayout>
然后编写PersonAdapter类:
public class PersonAdapter extends BaseAdapter { private Context context; private List<Person> personList; public PersonAdapter(Context context, List<Person> personList) { this.context = context; this.personList = personList; } @Override public int getCount() { return personList.size(); } @Override public Object getItem(int position) { return personList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View listItem = convertView; if (listItem == null) { // 加载布局 LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); listItem = inflater.inflate(R.layout.list_item_person, parent, false); } // 获取控件 TextView tvName = listItem.findViewById(R.id.tv_name); TextView tvBloodGroup = listItem.findViewById(R.id.tv_blood_group); TextView tvCity = listItem.findViewById(R.id.tv_city); // 绑定数据 Person currentPerson = personList.get(position); tvName.setText(currentPerson.getName()); tvBloodGroup.setText("血型: " + currentPerson.getBloodGroup()); tvCity.setText("城市: " + currentPerson.getCity()); return listItem; } }
几个重要的注意事项
- 避免主线程阻塞:如果数据库里数据量较大,建议把数据库查询操作放在子线程(比如用
AsyncTask、Coroutines或者ExecutorService),不然可能会导致ANR(应用无响应)。 - 字段名一致性:确保数据库表中的字段名和你代码里引用的完全一致(比如
blood_group不要写成bloodgroup),不然会抛出找不到列的异常。 - 动态城市数据:如果城市选项不是固定的,而是从数据库加载的,只需要把城市Spinner的适配器数据源换成从DBHelper查询出来的城市列表即可。
内容的提问来源于stack exchange,提问作者Shagun Sharma
相关产品推荐
相关产品推荐

