Android CheckBox勾选时仅最后一个EditText显示删除线问题排查
问题根因
checklistViewBinding被定义为ChecklistDetailActivity的全局成员变量,for循环逐个加载清单项布局时,每次inflate新布局都会覆盖该全局变量的引用,循环结束后checklistViewBinding永远指向最后一个加载的条目(测试用例中的c条目)。- 所有条目的CheckBox勾选监听器,操作的都是这个全局绑定实例持有的控件,无论点击a、b、c哪个条目的复选框,实际触发修改的都是最后一个c条目的文本和删除线效果,直接导致“点击a/b仅c条目出现删除线、c条目文本被替换为a/b内容”的异常。
- 代码中声明的
final int j = i未被实际使用,尽管监听器内捕获的索引取值正确,但由于操作的控件实例指向错误,索引无法发挥作用。
修复方案
- 删除Activity全局位置的
ChecklistViewBinding checklistViewBinding;声明,将该变量定义移到for循环内部,保证每个清单项持有独立的绑定实例,不会被后续循环的赋值覆盖。 - 监听器内部直接使用当前循环作用域内的绑定实例操作对应条目的控件,不再引用全局绑定对象。
修正后的核心实现代码如下:
public class ChecklistDetail extends AppCompatActivity { Toolbar toolbar; LinearLayout linearLayout; ActivityChecklistDetailBinding binding; // 移除全局的ChecklistViewBinding声明 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityChecklistDetailBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); binding.btnAddItemDetail.setVisibility(View.GONE); toolbar = findViewById(R.id.tool_bar); setSupportActionBar(toolbar); Intent intent = getIntent(); String status = intent.getStringExtra("status"); String content = intent.getStringExtra("content"); String[] statusSplit = status.split("\n"); String[] contentSplit = content.split("\n"); for (int i = 0; i < contentSplit.length; i++) { boolean state = statusSplit[i].equals("1"); // 绑定实例定义在循环内部,每个条目独立持有引用 ChecklistViewBinding checklistViewBinding = ChecklistViewBinding.inflate(getLayoutInflater()); binding.linearLayout.addView(checklistViewBinding.getRoot()); checklistViewBinding.etChecklistItem.setText(contentSplit[i]); checklistViewBinding.checkBox.setChecked(state); checklistViewBinding.imgDelete.setVisibility(View.INVISIBLE); SpannableString spannableString = new SpannableString(checklistViewBinding.etChecklistItem.getText().toString()); StrikethroughSpan strikethroughSpan = new StrikethroughSpan(); spannableString.setSpan(strikethroughSpan, 0, checklistViewBinding.etChecklistItem.getText().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); if (checklistViewBinding.checkBox.isChecked()) checklistViewBinding.etChecklistItem.setText(spannableString); else checklistViewBinding.etChecklistItem.setText(contentSplit[i]); final int itemIndex = i; checklistViewBinding.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { // 仅操作当前条目自身的控件,不会影响其他列表项 SpannableString spannableString = new SpannableString(checklistViewBinding.etChecklistItem.getText().toString()); StrikethroughSpan strikethroughSpan = new StrikethroughSpan(); spannableString.setSpan(strikethroughSpan, 0, checklistViewBinding.etChecklistItem.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); if (b) { checklistViewBinding.etChecklistItem.setText(spannableString); } else { checklistViewBinding.etChecklistItem.setText(contentSplit[itemIndex]); } } }); } } }
原实现布局效果参考:
内容的提问来源于stack exchange,提问作者nano tech
相关产品推荐
相关产品推荐

