Android中无需点击按钮自动计算填充BMI EditText失败求助
解决自动计算BMI及数据库存储问题
Hey there! Let's work through why your BMI isn't calculating automatically and fix the database issue too. Here are the key problems and their fixes:
1. 你忘记给身高/体重输入框绑定TextWatcher了
你已经实现了TextWatcher接口,但没有告诉etHeight和etWeight这两个输入框要监听文本变化,所以输入内容时不会触发calculate()方法。
在onCreate()方法里初始化完所有EditText后,加上这两行代码:
etHeight.addTextChangedListener(this); etWeight.addTextChangedListener(this);
2. BMI计算逻辑有两个关键错误
你当前的公式用了整数除法(会直接截断小数),而且没有把身高从厘米转换成米——这会导致计算结果极小甚至为0。我们重写calculate()方法,同时加入输入校验:
private void calculate() { String heightInput = etHeight.getText().toString().trim(); String weightInput = etWeight.getText().toString().trim(); // 如果输入为空,清空BMI显示 if (heightInput.isEmpty() || weightInput.isEmpty()) { etBMI.setText(""); return; } try { // 将身高从厘米转为米,用double类型保证计算精度 double heightInMeters = Double.parseDouble(heightInput) / 100.0; double weightInKg = Double.parseDouble(weightInput); // 校验身高为有效正数 if (heightInMeters <= 0) { etBMI.setText("无效身高"); return; } // 计算BMI并保留两位小数,让结果更友好 double bmiValue = weightInKg / (heightInMeters * heightInMeters); etBMI.setText(String.format("%.2f", bmiValue)); } catch (NumberFormatException e) { // 处理非数字输入的情况 etBMI.setText("输入无效"); } }
3. 数据库插入存在校验和安全漏洞
你当前的代码没有在插入数据库前校验输入是否为空或有效,容易导致崩溃或存入空值;而且用字符串拼接SQL语句有SQL注入风险。我们修复btnNext的点击事件:
首先,修正全局btnNext变量的定义(你之前在局部重新定义了变量,虽然不影响但不够规范):
// 把这行: // Button btnNext = (Button) findViewById(R.id.btnNext); // 改成: btnNext = (Button) findViewById(R.id.btnNext);
然后更新点击事件逻辑:
btnNext.setOnClickListener(new OnClickListener() { public void onClick(View V) { String name = etName.getText().toString().trim(); String ageStr = etAge.getText().toString().trim(); String heightStr = etHeight.getText().toString().trim(); String weightStr = etWeight.getText().toString().trim(); String bmi = etBMI.getText().toString().trim(); // 检查所有必填字段是否填写 if (name.isEmpty() || ageStr.isEmpty() || heightStr.isEmpty() || weightStr.isEmpty() || bmi.isEmpty()) { Toast.makeText(Userreg.this, "请填写所有必填字段", Toast.LENGTH_SHORT).show(); return; } try { int age = Integer.parseInt(ageStr); int height = Integer.parseInt(heightStr); int weight = Integer.parseInt(weightStr); // 使用参数化SQL防止SQL注入风险 String sql = "INSERT INTO UserInfo (Name,Age,Height,Weight,BMI) VALUES (?, ?, ?, ?, ?)"; db.execSQL(sql, new Object[]{name, age, height, weight, bmi}); Toast.makeText(Userreg.this, "注册成功!", Toast.LENGTH_SHORT).show(); Intent msg3 = new Intent(Userreg.this, Regsuccess.class); startActivity(msg3); } catch (NumberFormatException e) { Toast.makeText(Userreg.this, "年龄、身高、体重请输入有效数字", Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(Userreg.this, "数据库错误:" + e.getMessage(), Toast.LENGTH_LONG).show(); } } });
4. 额外优化:数据库存储位置与资源清理
你当前把数据库存在SD卡根目录,需要额外权限且不安全。改用内部存储更稳妥,不需要额外权限:
String createDatabase(String sql, String dbName) { try { // 使用内部存储(无需权限) db = openOrCreateDatabase(dbName, MODE_PRIVATE, null); db.execSQL(sql); } catch (Exception e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show(); return "Error opening DB"; } return ""; }
同时,在onDestroy()里关闭数据库,避免资源泄漏:
@Override protected void onDestroy() { super.onDestroy(); if (db != null && db.isOpen()) { db.close(); } }
把这些修改全部应用后,用户输入身高体重时BMI会自动计算填充,数据库也能正确存储有效数据了。
内容的提问来源于stack exchange,提问作者Kelvin How
相关产品推荐
相关产品推荐

