如何在Android中用Kotlin实现带EditText的自定义ListView并获取输入值
解决方案
在Android中,由于ListView的视图复用机制,不能像iOS那样直接遍历单元格实例获取值,更可靠的方式是通过数据源绑定同步EditText的输入,或针对可见视图做临时处理,以下是两种Kotlin实现方案:
方案一:绑定EditText输入到数据源(推荐)
这种方式符合Android设计思路,所有输入值会实时同步到数据源,无论列表项是否在屏幕上,都能完整获取所有值。
1. 定义数据模型
创建数据类存储每个列表项的输入值:
data class ListItem(var inputText: String = "")
2. 自定义ListView Adapter
在Adapter中为EditText添加TextWatcher,将输入内容实时同步到对应数据模型:
class InputListAdapter( private val context: Context, private val itemList: MutableList<ListItem> ) : BaseAdapter() { override fun getCount(): Int = itemList.size override fun getItem(position: Int): ListItem = itemList[position] override fun getItemId(position: Int): Long = position.toLong() override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { val view = convertView ?: LayoutInflater.from(context) .inflate(R.layout.list_item_layout, parent, false) val inputEt = view.findViewById<EditText>(R.id.et_number_input) val currentItem = getItem(position) // 移除旧的TextWatcher,避免视图复用时重复绑定 inputEt.removeTextChangedListeners() // 设置当前项的已有值 inputEt.setText(currentItem.inputText) // 绑定输入变化到数据源 inputEt.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { currentItem.inputText = s?.toString() ?: "" } }) return view } }
3. 在Activity中使用
初始化列表、添加条目,点击按钮时直接遍历数据源获取所有值:
class MainActivity : AppCompatActivity() { private lateinit var itemList: MutableList<ListItem> private lateinit var listAdapter: InputListAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val listView = findViewById<ListView>(R.id.list_view) val btnAddItem = findViewById<Button>(R.id.btn_add_item) val btnCalculate = findViewById<Button>(R.id.btn_calculate) // 初始化数据源和适配器 itemList = mutableListOf() listAdapter = InputListAdapter(this, itemList) listView.adapter = listAdapter // 添加新条目 btnAddItem.setOnClickListener { itemList.add(ListItem()) listAdapter.notifyDataSetChanged() } // 获取所有输入值并运算 btnCalculate.setOnClickListener { // 过滤无效输入,转换为Double类型 val validNumbers = itemList.mapNotNull { it.inputText.toDoubleOrNull() } // 示例:计算总和 val total = validNumbers.sum() // 这里添加你的运算逻辑,比如弹窗显示结果 Toast.makeText(this, "总和:$total", Toast.LENGTH_SHORT).show() } } }
方案二:遍历可见列表项获取值(仅适用于短列表)
如果列表不会很长,所有条目基本都在屏幕内,可以直接遍历ListView的可见子视图获取值,但这种方式无法获取屏幕外的条目值(那些视图已被复用回收):
btnCalculate.setOnClickListener { val validNumbers = mutableListOf<Double>() val listView = findViewById<ListView>(R.id.list_view) for (i in 0 until listView.childCount) { val itemView = listView.getChildAt(i) val inputEt = itemView.findViewById<EditText>(R.id.et_number_input) inputEt.text.toString().toDoubleOrNull()?.let { validNumbers.add(it) } } val total = validNumbers.sum() Toast.makeText(this, "可见条目总和:$total", Toast.LENGTH_SHORT).show() }
内容的提问来源于stack exchange,提问作者AverageMoss
相关产品推荐
相关产品推荐

