Android 扫码内容 不填入 EditText 的一种解决办法

621 阅读1分钟

问题描述

例如在 BuyFragment 购买页 支持在输入框 EditText 软键盘输入商品编号加入购物车,同时支持 扫码 自动加入购物车的需求场景,但是焦点在 EditText 时,扫码内容会直接输入 EditText,不符合业务需求。

解决办法

  1. BuyFragment 购买页初始化时,通过 setOnKeyListener 同时 监听 根 View binding.root 和 手动输入框 EditText binding.etId
  2. 判断 binding.etId 返回的 keyEventdeviceId 若 > 0 则为硬件设备输入,此时将原本在 EditText 的焦点 转移 根 View binding.root,防止扫码内容输入 EditText
  3. 再通过 binding.root 的监听处理扫描内容,参考代码如下:
class BuyFragment : Fragment() {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    handleViewScanData(binding.root)
    binding.etId.setOnKeyListener { _, _, keyEvent ->
    // deviceId > 0 为硬件设备输入
    if (keyEvent.deviceId > 0) {
        requestViewFocus(binding.root)
        true
    } else {
        false
    }
    binding.etId.requestFocus()
}

/**
 * view 设置焦点
 */
fun requestViewFocus(view: View) {
    view.isFocusableInTouchMode = true
    view.requestFocus()
}

/**
 * view 输入事件处理
 */
fun handleViewScanData(view: View) {
    requestViewFocus(view)
    view.setOnKeyListener { _, _, keyEvent ->
        ...
        true
    }
}
...

可能遇到的问题
View binding.root 获得焦点时出现选中框,如下图:

rootView 获取焦点.png

  • 解决办法:布局中新增一个 1像素 View 作为 焦点。
<View
    android:id="@+id/v_point"
    android:layout_width="1dp"
    android:layout_height="1dp" />

加入 binding.vPoint 后参考代码如下:

class BuyFragment : Fragment() {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    handleViewScanData(binding.vPoint)
    binding.etId.setOnKeyListener { _, _, keyEvent ->
    if (keyEvent.deviceId > 0) {
        requestViewFocus(binding.vPoint)
        true
    } else {
        false
    }
    binding.etId.requestFocus()
}

/**
 * view 设置焦点
 */
fun requestViewFocus(view: View) {
    view.isFocusableInTouchMode = true
    view.requestFocus()
}

/**
 * view 输入事件处理
 */
fun handleViewScanData(view: View) {
    requestViewFocus(view)
    view.setOnKeyListener { _, _, keyEvent ->
        ...
        true
    }
}
...

参考资料