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

Android ExpandableListView条目软键盘弹出时光标自动跳转问题

ExpandableListView 输入框焦点自动跳转问题解决方案

问题复现

我在应用中使用了ExpandableListView,此前项目中多次使用该组件均无运行异常,本次遇到如下问题:

  • 点击折扣价、价格对应的输入框准备输入内容时,底部弹出数字键盘,光标会自动跳转到当前行的尺寸输入框中,该问题每次软键盘弹出时都会触发

已尝试方案缺陷

  • 方案1:在AndroidManifest清单文件中为对应Activity设置android:windowSoftInputMode="adjustNothing"属性

    该配置可以解决光标跳转问题,但部分列表内容会被软键盘遮挡,用户隐藏软键盘前无法查看被遮挡内容,体验极差

  • 方案2:将价格输入框的inputType属性设置为text

    该配置下软键盘仅会弹出一次,后续点击价格或折扣输入框时软键盘不会重新弹出,虽然不会触发光标跳转,但不符合数字输入的交互需求,无法正常使用

问题截图

问题界面截图


根因分析

该问题本质是软键盘弹出触发Activity窗口重绘,ExpandableListView会重新调用getChildView()刷新可见区域的子Item布局。如果你没有在Adapter中正确保存和恢复每个输入框的焦点状态,重绘后系统会默认将焦点分配给当前Item布局中focusable优先级最高的第一个输入框,也就是你布局里排在前面的尺寸输入框。

你观察到的两种临时解决方案的逻辑也完全匹配该根因:

  1. 用adjustNothing时窗口不会因为软键盘弹出触发重绘,所以不会触发Item刷新,自然不会出现焦点跳转
  2. 把inputType改成text时系统不会重复触发软键盘弹出逻辑,也就不会触发窗口重绘,所以也不会复现问题

修复方案

你可以按以下步骤修复,不需要修改原有窗口配置和输入框输入类型,完全兼容原有交互逻辑:

  1. 在Adapter中定义变量保存当前获得焦点的输入框位置信息:
// 保存当前焦点所在的组位置、子位置、焦点输入框类型
private int currentFocusGroupPos = -1;
private int currentFocusChildPos = -1;
// 输入框类型可自定义:0=无焦点 1=尺寸输入框 2=价格输入框 3=折扣输入框
private int currentFocusViewType = 0;
  1. 给每个子Item的三个输入框设置OnFocusChangeListener,当输入框获得焦点时更新上述保存的位置变量
  2. 在getChildView()方法渲染完Item布局后,判断当前渲染的位置是否和保存的焦点位置一致,如果一致,手动给对应的输入框请求焦点:
// 此处为getChildView()内逻辑,groupPosition、childPosition为当前渲染项的位置
if (groupPosition == currentFocusGroupPos && childPosition == currentFocusChildPos) {
    switch (currentFocusViewType) {
        case 1:
            sizeEditText.requestFocus();
            break;
        case 2:
            priceEditText.requestFocus();
            break;
        case 3:
            discountEditText.requestFocus();
            break;
    }
}
  1. 可选优化:如果你的输入框内容需要持久化保存,也需要在Adapter中维护一份输入内容的缓存列表,在getChildView()时给对应输入框赋值,避免重绘后内容丢失。

内容的提问来源于stack exchange,提问作者Zohab Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:15:03