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

如何在Android Studio中为安卓饮品咖啡因应用添加带搜索排序的数据库?

安卓饮品咖啡因信息应用数据库及功能实现方案

一、数据库选型与基础配置

推荐使用Room Persistence Library,安卓官方ORM框架,无需手写复杂SQL,新手友好。

1. 添加依赖

在Module级build.gradle中引入Room依赖:

dependencies {
    def room_version = "2.6.1"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
}

2. 创建实体类

对应你的6列数据,创建Drink.java:

@Entity(tableName = "drinks")
public class Drink {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String name; // 饮品名称
    private String category; // 饮品类别
    private float servingSize; // 份容量
    private float totalCaffeine; // 咖啡因总量
    private float caffeinePer100ml; // 每100ml咖啡因含量

    // 构造方法、getter、setter自行补充
}

3. 定义Dao接口

封装所有数据库操作方法,创建DrinkDao.java:

@Dao
public interface DrinkDao {
    // 用户录入数据
    @Insert
    void insertDrink(Drink drink);

    // 按指定列升序查询所有数据
    @Query("SELECT * FROM drinks ORDER BY :sortColumn ASC")
    List<Drink> getAllDrinksAsc(String sortColumn);

    // 按指定列降序查询所有数据
    @Query("SELECT * FROM drinks ORDER BY :sortColumn DESC")
    List<Drink> getAllDrinksDesc(String sortColumn);

    // 按类别筛选
    @Query("SELECT * FROM drinks WHERE category = :category ORDER BY name ASC")
    List<Drink> getDrinksByCategory(String category);

    // 搜索(匹配名称或类别)
    @Query("SELECT * FROM drinks WHERE name LIKE '%' || :searchQuery || '%' OR category LIKE '%' || :searchQuery || '%'")
    List<Drink> searchDrinks(String searchQuery);
}

4. 创建数据库实例

用单例模式避免重复初始化,创建AppDatabase.java:

@Database(entities = {Drink.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract DrinkDao drinkDao();

    private static volatile AppDatabase INSTANCE;
    public static AppDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (AppDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AppDatabase.class, "drink_database")
                            .build();
                }
            }
        }
        return INSTANCE;
    }
}

二、Excel现有数据导入

在App启动时检查数据库,为空则批量插入Excel中的数据:

// 在Application类或首页Activity的onCreate方法中执行
AppDatabase db = AppDatabase.getInstance(this);
new Thread(() -> {
    List<Drink> drinks = db.drinkDao().getAllDrinksAsc("name");
    if (drinks.isEmpty()) {
        // 示例:添加Excel中的一条数据
        db.drinkDao().insertDrink(new Drink("冰美式", "现磨咖啡", 350f, 150f, 42.86f));
        // 批量添加其余Excel数据...
    }
}).start();

三、核心功能实现

1. 搜索功能

监听搜索框文本变化,实时查询数据:

searchEditText.addTextChangedListener(new TextWatcher() {
    @Override
    public void afterTextChanged(Editable s) {
        String query = s.toString().trim();
        new Thread(() -> {
            List<Drink> result = db.drinkDao().searchDrinks(query);
            runOnUiThread(() -> {
                // 更新RecyclerView适配器数据
                drinkAdapter.setData(result);
            });
        }).start();
    }

    @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
    @Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
});

2. 按类别筛选

给类别选择控件(如Spinner)添加选择监听:

categorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        String selectedCategory = parent.getItemAtPosition(position).toString();
        new Thread(() -> {
            List<Drink> result;
            if (selectedCategory.equals("全部")) {
                result = db.drinkDao().getAllDrinksAsc("name");
            } else {
                result = db.drinkDao().getDrinksByCategory(selectedCategory);
            }
            runOnUiThread(() -> drinkAdapter.setData(result));
        }).start();
    }

    @Override public void onNothingSelected(AdapterView<?> parent) {}
});

3. 数值列排序

给排序按钮添加点击事件,切换升降序:

private boolean isAscending = true;

sortButton.setOnClickListener(v -> {
    isAscending = !isAscending;
    new Thread(() -> {
        List<Drink> result;
        // 示例:按每100ml咖啡因含量排序
        if (isAscending) {
            result = db.drinkDao().getAllDrinksAsc("caffeinePer100ml");
        } else {
            result = db.drinkDao().getAllDrinksDesc("caffeinePer100ml");
        }
        runOnUiThread(() -> {
            drinkAdapter.setData(result);
            sortButton.setText(isAscending ? "升序" : "降序");
        });
    }).start();
});

4. 用户数据录入

创建录入界面,获取用户输入后插入数据库:

saveButton.setOnClickListener(v -> {
    String name = nameEditText.getText().toString().trim();
    String category = categoryEditText.getText().toString().trim();
    float servingSize = Float.parseFloat(servingSizeEditText.getText().toString());
    float totalCaffeine = Float.parseFloat(totalCaffeineEditText.getText().toString());
    float per100ml = totalCaffeine / servingSize * 100; // 自动计算每100ml含量

    Drink newDrink = new Drink(name, category, servingSize, totalCaffeine, per100ml);
    new Thread(() -> {
        db.drinkDao().insertDrink(newDrink);
        runOnUiThread(() -> {
            Toast.makeText(this, "数据已保存", Toast.LENGTH_SHORT).show();
            finish();
        });
    }).start();
});

四、新手注意事项

  • 所有数据库操作必须在子线程执行,避免阻塞主线程;也可使用Room结合Coroutines简化线程处理
  • 实体类字段名需与Dao查询语句中的列名一致,或用@ColumnInfo指定别名
  • 测试阶段可临时添加allowMainThreadQueries()允许主线程操作,但正式发布必须移除
  • 后续数据库版本升级需编写迁移逻辑,防止数据丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:27:44