You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:48:28