动态添加布局至LinearLayout时ID冲突导致文本设置错误的解决咨询
问题原因与解决方案
你猜的完全没错!问题的核心就是动态加载的布局子控件ID重复。Android中,当你调用全局的findViewById时,系统会在整个Activity的视图树里返回第一个匹配该ID的控件——所以不管你点击的是第几个加载项的EditText,最终都会修改第一个出现的那个控件的内容。
下面给你两种简单有效的解决方法,优先推荐第一种:
方法一:直接传递EditText实例(最简便)
不要通过ID来定位控件,而是直接把点击的EditText实例传给showTimePicker函数,这样就能精准操作目标控件:
- 修改
showTimePicker函数的参数,把viewId: Int换成targetEditText: EditText:
fun showTimePicker(targetEditText: EditText) { val cal = Calendar.getInstance() val timeSetListener = TimePickerDialog.OnTimeSetListener { timePicker, hour, minute -> cal.set(Calendar.HOUR_OF_DAY, hour) cal.set(Calendar.MINUTE, minute) // 直接操作传入的EditText实例 targetEditText.setText(SimpleDateFormat("HH:mm").format(cal.time)) } TimePickerDialog(this, timeSetListener, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true).show() }
- 修改点击事件的调用逻辑,直接传递当前的EditText:
在addNewConsultingTime函数里,把原来的点击事件代码替换成:
// 处理consultingTo的点击 consultingTo?.let { et -> et.setOnClickListener { showTimePicker(et) } } // 处理consultingFrom的点击 consultingFrom?.let { et -> et.setOnClickListener { showTimePicker(et) } }
这样每次点击时,都会把当前被点击的EditText实例传给时间选择器,回调时自然会修改正确的控件。
方法二:为动态生成的控件设置唯一ID
如果你坚持要用ID来传递,可以给每个动态加载的控件生成唯一ID:
- 在
addNewConsultingTime函数里,为每个EditText设置唯一ID:
consultingFrom?.id = View.generateViewId() consultingTo?.id = View.generateViewId()
- 然后修改
showTimePicker函数,从consultingTimeContainer里查找目标控件(而不是全局的findViewById):
fun showTimePicker(viewId: Int) { val cal = Calendar.getInstance() val timeSetListener = TimePickerDialog.OnTimeSetListener { timePicker, hour, minute -> cal.set(Calendar.HOUR_OF_DAY, hour) cal.set(Calendar.MINUTE, minute) // 从容器中查找对应ID的控件,而不是全局查找 consultingTimeContainer.findViewById<EditText>(viewId).setText(SimpleDateFormat("HH:mm").format(cal.time)) } TimePickerDialog(this, timeSetListener, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true).show() }
不过这种方法比第一种麻烦,而且需要额外处理ID的生成,所以更推荐第一种方案。
内容的提问来源于stack exchange,提问作者Aswin .A.S
相关产品推荐
相关产品推荐

