You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中SQLite资产库数据匹配筛选后展示至RecyclerView求助

宠物领养APP开发建议

整体方向没问题,基于你现有的代码和需求,以下是具体的优化和补全建议:

一、数据库部分优化

  1. SQLiteAssetHelper 配置检查
    确保你的PetAdoption.db数据库文件放在项目的assets/databases目录下(无此目录需手动创建),数据库表结构包含name、age、gender等要查询的字段,版本号DBVERSION需和数据库文件版本匹配。

  2. DatabaseAccess 类修正

    • 修正拼写错误:getReadableDataBase()改为getReadableDatabase()
    • 优化单例实现,避免内存泄漏和多线程问题:
      private static volatile DatabaseAccess instance; // 加volatile防止指令重排
      
      public static DatabaseAccess getInstance(Context context) {
          if (instance == null) {
              synchronized (DatabaseAccess.class) {
                  if (instance == null) {
                      // 使用Application Context避免Activity销毁导致的内存泄漏
                      instance = new DatabaseAccess(context.getApplicationContext());
                  }
              }
          }
          return instance;
      }
      
    • 统一数据库操作入口,避免重复获取实例:
      // 移除多余的getWritableDatabase和getReadableDatabase方法,改用成员变量database
      public SQLiteDatabase getDatabase() {
          if (database == null || !database.isOpen()) {
              database = openHelper.getWritableDatabase();
          }
          return database;
      }
      

二、MainActivity 基础修正

  1. 初始化context变量,避免空指针:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 直接使用当前Activity作为上下文,或用getApplicationContext()
        DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
        // 查询逻辑移到提交按钮点击事件中,不要在onCreate直接执行空查询
    }
    
  2. 将查询逻辑绑定到提交按钮的点击事件,等用户选完复选框后再触发筛选。

三、实现复选框筛选逻辑

  1. 定义宠物数据模型
    创建Pet.java类对应数据库中的宠物信息:

    public class Pet {
        private String name;
        private int age;
        private String gender;
    
        public Pet(String name, int age, String gender) {
            this.name = name;
            this.age = age;
            this.gender = gender;
        }
    
        // Getter方法
        public String getName() { return name; }
        public int getAge() { return age; }
        public String getGender() { return gender; }
    }
    
  2. 动态生成查询语句
    在提交按钮点击事件中,收集复选框选中状态,拼接SQL查询条件:

    submitBtn.setOnClickListener(v -> {
        DatabaseAccess dbAccess = DatabaseAccess.getInstance(this);
        SQLiteDatabase db = dbAccess.getDatabase();
    
        StringBuilder whereClause = new StringBuilder();
        List<String> queryArgs = new ArrayList<>();
    
        // 示例:四个问题对应的复选框条件(根据你的实际需求调整)
        // 问题1:宠物类型(猫/狗)
        if (catCheckbox.isChecked()) {
            appendCondition(whereClause, queryArgs, "type = ?", "猫");
        }
        if (dogCheckbox.isChecked()) {
            appendCondition(whereClause, queryArgs, "type = ?", "狗");
        }
        // 问题2:年龄区间(如<3岁)
        if (youngCheckbox.isChecked()) {
            appendCondition(whereClause, queryArgs, "age < ?", "3");
        }
        // 问题3:性别(公/母)
        if (maleCheckbox.isChecked()) {
            appendCondition(whereClause, queryArgs, "gender = ?", "公");
        }
        // 问题4:是否绝育
        if (sterilizedCheckbox.isChecked()) {
            appendCondition(whereClause, queryArgs, "sterilized = ?", "1");
        }
    
        // 生成完整查询语句
        String query = "SELECT name, age, gender FROM pets";
        if (whereClause.length() > 0) {
            query += " WHERE " + whereClause.toString();
        }
    
        // 查询并转换为Pet列表
        List<Pet> petList = new ArrayList<>();
        Cursor cursor = db.rawQuery(query, queryArgs.toArray(new String[0]));
        if (cursor.moveToFirst()) {
            do {
                String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
                int age = cursor.getInt(cursor.getColumnIndexOrThrow("age"));
                String gender = cursor.getString(cursor.getColumnIndexOrThrow("gender"));
                petList.add(new Pet(name, age, gender));
            } while (cursor.moveToNext());
        }
        cursor.close();
    
        // 将petList传入RecyclerView展示
        updateRecyclerView(petList);
    });
    

    辅助方法appendCondition(根据需求选择AND/OR拼接条件):

    private void appendCondition(StringBuilder whereClause, List<String> args, String condition, String arg) {
        if (whereClause.length() > 0) {
            whereClause.append(" OR "); // 类型多选用OR,其他条件可改用AND
        }
        whereClause.append(condition);
        args.add(arg);
    }
    

四、RecyclerView 实现

  1. 创建列表项布局(如item_pet.xml),包含三个TextView分别显示姓名、年龄、性别。
  2. 实现Adapter和ViewHolder:
    public class PetAdapter extends RecyclerView.Adapter<PetAdapter.PetViewHolder> {
        private List<Pet> petList;
    
        public PetAdapter(List<Pet> petList) {
            this.petList = petList;
        }
    
        public void setPetList(List<Pet> petList) {
            this.petList = petList;
            notifyDataSetChanged();
        }
    
        @NonNull
        @Override
        public PetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_pet, parent, false);
            return new PetViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(@NonNull PetViewHolder holder, int position) {
            Pet pet = petList.get(position);
            holder.nameTv.setText(pet.getName());
            holder.ageTv.setText(String.format("年龄:%d岁", pet.getAge()));
            holder.genderTv.setText(String.format("性别:%s", pet.getGender()));
        }
    
        @Override
        public int getItemCount() {
            return petList != null ? petList.size() : 0;
        }
    
        public static class PetViewHolder extends RecyclerView.ViewHolder {
            TextView nameTv, ageTv, genderTv;
    
            public PetViewHolder(@NonNull View itemView) {
                super(itemView);
                nameTv = itemView.findViewById(R.id.tv_name);
                ageTv = itemView.findViewById(R.id.tv_age);
                genderTv = itemView.findViewById(R.id.tv_gender);
            }
        }
    }
    
  3. 在MainActivity中初始化RecyclerView:
    private RecyclerView petRecyclerView;
    private PetAdapter petAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // ...其他初始化代码
    
        petRecyclerView = findViewById(R.id.recycler_view_pets);
        petRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        petAdapter = new PetAdapter(new ArrayList<>());
        petRecyclerView.setAdapter(petAdapter);
    }
    
    private void updateRecyclerView(List<Pet> petList) {
        petAdapter.setPetList(petList);
    }
    

五、关键注意事项

  • 数据库操作不能在主线程:直接在主线程执行查询会导致ANR(应用无响应),建议用AsyncTask或Thread配合Handler处理查询逻辑。
  • 资源释放:在Activity的onDestroy方法中关闭数据库连接:
    @Override
     protected void onDestroy() {
         super.onDestroy();
         DatabaseAccess.getInstance(this).closeDatabase();
     }
    
  • 测试优先:先单独测试数据库查询是否能正确获取数据,再逐步整合复选框筛选和RecyclerView展示,避免一次性写大量代码难以调试。

内容的提问来源于stack exchange,提问作者Uzume316

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 02:55:31