解决从可填充EditText取值存入ArrayList始终为0的问题
问题分析与解决方案
嘿,我看了你的代码,发现几个可能导致你获取的值始终是0的问题,咱们一步步来解决:
核心问题1:索引(position)的绑定逻辑有隐患
你现在用scoreList.size()来获取position,然后立刻往列表里加0。虽然单次循环看起来没问题,但如果addCourses()方法被多次调用,或者列表操作逻辑有变动,很容易导致索引和EditText的对应关系错乱。用循环的i作为索引会更直接可靠,因为每个循环生成的View正好对应列表的第i个位置。
核心问题2:没有处理输入异常和空值
当用户输入空字符串或者非数字内容时,Integer.parseInt()会直接抛出异常,导致afterTextChanged里的赋值代码根本不执行,列表里的值就会停留在初始的0。
核心问题3:可能存在重复添加View和数据的情况
如果addCourses()被多次调用,你没有清空之前的View和列表数据,会导致新添加的View对应列表后面的位置,但你读取的还是前面的初始0值。
修正后的完整代码
public void addCourses() { LayoutInflater inflater = LayoutInflater.from(this); // 先清空已有的课程View和数据列表,避免重复添加导致混乱 this.courses.removeAllViews(); this.scoreList.clear(); this.totalList.clear(); for (int i = 0; i < this.coursesList.size(); i++) { View v = inflater.inflate(R.layout.item_course, null, false); this.courses.addView(v); // 先往列表添加初始值0,然后用循环的i作为当前项的索引 CalculateActivity.this.scoreList.add(0); final int position = i; CalculateActivity.this.totalList.add(0); final int position2 = i; EditText scoreEt = (EditText) v.findViewById(R.id.Score); EditText totalEt = (EditText) v.findViewById(R.id.Total); scoreEt.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { try { String input = editable.toString().trim(); // 处理空输入的情况,设为0 int perc = input.isEmpty() ? 0 : Integer.parseInt(input); CalculateActivity.this.scoreList.set(position, perc); } catch (NumberFormatException e) { // 输入非数字时重置为0,并提示用户 CalculateActivity.this.scoreList.set(position, 0); Toast.makeText(CalculateActivity.this, "请输入有效的数字", Toast.LENGTH_SHORT).show(); } } }); totalEt.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { try { String input = editable.toString().trim(); int hundredth = input.isEmpty() ? 0 : Integer.parseInt(input); CalculateActivity.this.totalList.set(position2, hundredth); } catch (NumberFormatException e) { CalculateActivity.this.totalList.set(position2, 0); Toast.makeText(CalculateActivity.this, "请输入有效的数字", Toast.LENGTH_SHORT).show(); } } }); } }
额外注意点
- 读取数据的时机:不要在
addCourses()执行完立刻读取scoreList和totalList,这时候用户还没输入内容,值肯定是0。应该在用户输入完成后,比如点击“计算”按钮时再读取列表数据。 - 动态添加单个课程项:如果是点击按钮逐个添加课程,而不是一次性循环添加,那可以用下面的逻辑:
public void addSingleCourse() { LayoutInflater inflater = LayoutInflater.from(this); View v = inflater.inflate(R.layout.item_course, null, false); this.courses.addView(v); // 添加初始值后,用列表最后一位的索引作为当前项的position this.scoreList.add(0); final int position = this.scoreList.size() - 1; this.totalList.add(0); final int position2 = this.totalList.size() - 1; // 后续EditText的监听器逻辑和上面一致 }
内容的提问来源于stack exchange,提问作者Junseok Joon Kang
相关产品推荐
相关产品推荐

