Android Studio中如何按熔点范围过滤SQL数据库并在ListView展示
问题分析与解决方案
你的代码存在两个核心问题,导致过滤逻辑完全失效:
1. SQL查询语句的语法错误
在filterData方法中,你用单引号'包裹了表名和字段名——这是SQL语法的典型错误:单引号仅用于包裹字符串值,而表名、字段名需要用反引号(`)包裹(或直接省略,只要名称不含特殊字符)。这个错误会让数据库无法识别你的WHERE过滤条件,最终返回全量数据。
修复filterData方法
public Cursor filterData(double max, double min){ // 用反引号处理表名/字段名,同时改用参数化查询避免SQL注入 String query = "SELECT * FROM " + DBHandler.TABLE_ALLOY_DETAILS + " WHERE " + MELTING_POINT + " BETWEEN ? AND ?"; Cursor c = db.rawQuery(query, new String[]{String.valueOf(min), String.valueOf(max)}); if(c != null){ c.moveToFirst(); } return c; }
这里顺便改成了参数化查询,比直接拼接字符串更安全,还能避免数值类型转换的潜在问题。
2. 过滤结果未传递到展示页面
你在过滤页面调用了myDB.filterData,但这个过滤后的Cursor并没有传递到ListView展示页面——展示页面的populateListView方法直接调用getAllRows获取全量数据,完全没用到过滤逻辑的结果。
解决数据传递问题
需要把过滤参数(max和min)通过Intent传递到展示页面,再在展示页面执行过滤查询:
第一步:修改过滤页面的跳转逻辑,传递参数
save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 先设置默认值,再根据输入覆盖,简化判断逻辑 double maxMP = 10000; double minMP = 0; if(!TextUtils.isEmpty(mpMaxInput.getText())){ maxMP = Double.parseDouble(mpMaxInput.getText().toString()); } if(!TextUtils.isEmpty(mpMinInput.getText())){ minMP = Double.parseDouble(mpMinInput.getText().toString()); } // 将参数放入Intent,跳转到展示页面 Intent intent = new Intent(YourFilterActivity.this, MasActivity.class); // 替换为你的过滤页面类名 intent.putExtra("MAX_MP", maxMP); intent.putExtra("MIN_MP", minMP); startActivity(intent); } });
第二步:修改展示页面,接收参数并执行过滤
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mas); overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out); // 获取Intent传递的过滤参数 Intent intent = getIntent(); double maxMP = intent.getDoubleExtra("MAX_MP", 10000); double minMP = intent.getDoubleExtra("MIN_MP", 0); openDB(); // 传入过滤参数,执行查询并填充ListView populateListView(maxMP, minMP); } // 修改populateListView方法,接收过滤参数 private void populateListView(double maxMP, double minMP){ Cursor cursor = myDB.filterData(maxMP, minMP); // 调用过滤查询而非全量查询 String[] fromFieldNames = new String[]{DBHandler.ALLOY_NAME, DBHandler.MELTING_POINT}; int[] toViewIDs = new int[]{R.id.textView48, R.id.textView49}; SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter( getBaseContext(), R.layout.item_layout, cursor, fromFieldNames, toViewIDs, 0 ); ListView list = findViewById(R.id.listView); list.setAdapter(myCursorAdaptor); }
额外检查项
- 确保
MELTING_POINT常量的字段名和数据库表中实际定义的字段名完全一致(SQLite默认大小写不敏感,但最好保持统一)。 - 可以在
filterData方法中打印Cursor的行数,验证过滤是否生效:Log.d("Filter", "过滤后行数:" + c.getCount())。 - 确认
DBHandler的open()方法正确获取了数据库实例,避免因数据库未打开导致的查询异常。
内容的提问来源于stack exchange,提问作者Ved Ameresh
相关产品推荐
相关产品推荐

