feat: opt 编码输入
This commit is contained in:
246
.docs/大写字母数字输入过滤器使用指南.md
Normal file
246
.docs/大写字母数字输入过滤器使用指南.md
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
# 大写字母数字输入过滤器使用指南
|
||||||
|
|
||||||
|
## 功能说明
|
||||||
|
|
||||||
|
为 EditText 提供输入过滤功能:
|
||||||
|
- ✅ 只允许输入大写字母(A-Z)和数字(0-9)
|
||||||
|
- ✅ 小写字母自动转为大写
|
||||||
|
- ✅ 自动过滤中文、特殊符号、空格等所有非法字符
|
||||||
|
|
||||||
|
## 核心实现
|
||||||
|
|
||||||
|
**位置**: `module_base/src/main/java/com/lukouguoji/module_base/ktx/EditTextKtx.kt`
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
/**
|
||||||
|
* 大写字母和数字输入过滤器
|
||||||
|
*/
|
||||||
|
class UpperCaseAlphanumericInputFilter : InputFilter {
|
||||||
|
// 实现细节...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为 EditText 设置大写字母和数字输入过滤器
|
||||||
|
*/
|
||||||
|
fun EditText.setUpperCaseAlphanumericFilter() {
|
||||||
|
this.filters = arrayOf(UpperCaseAlphanumericInputFilter())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
|
||||||
|
### 方式一:直接为 EditText 设置(最简单)
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
||||||
|
|
||||||
|
// Activity 中
|
||||||
|
override fun initOnCreate(savedInstanceState: Bundle?) {
|
||||||
|
// 为普通 EditText 设置
|
||||||
|
binding.editText.setUpperCaseAlphanumericFilter()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式二:为 PadDataLayoutNew 内部的 EditText 设置
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
||||||
|
|
||||||
|
// Activity 中
|
||||||
|
override fun initOnCreate(savedInstanceState: Bundle?) {
|
||||||
|
// PadDataLayoutNew 内部有一个 et 属性,是 EditText
|
||||||
|
binding.carIdInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
binding.uldNoInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
binding.impCodeInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方式三:在自定义 View 中设置
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
||||||
|
|
||||||
|
class CustomView : FrameLayout {
|
||||||
|
private val editText: EditText
|
||||||
|
|
||||||
|
init {
|
||||||
|
// 初始化后设置
|
||||||
|
editText.setUpperCaseAlphanumericFilter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 实际应用案例
|
||||||
|
|
||||||
|
### 案例1:板箱过磅页面(GjcBoxWeighingAddActivity)
|
||||||
|
|
||||||
|
**需求**: 架子车号、ULD编码、IMP代码只允许输入大写字母和数字
|
||||||
|
|
||||||
|
**实现**:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// GjcBoxWeighingAddActivity.kt
|
||||||
|
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
||||||
|
|
||||||
|
override fun initOnCreate(savedInstanceState: Bundle?) {
|
||||||
|
setBackArrow("板箱过磅")
|
||||||
|
binding.viewModel = viewModel
|
||||||
|
viewModel.initOnCreated(this)
|
||||||
|
|
||||||
|
// 为架子车号、ULD编码、IMP代码添加大写字母和数字的输入限制
|
||||||
|
binding.carIdInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
binding.uldNoInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
binding.impCodeInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**效果**:
|
||||||
|
- 输入 `abc123` → 自动变成 `ABC123`
|
||||||
|
- 输入 `板箱_88` → 自动变成 `88`
|
||||||
|
- 输入 `test@#456` → 自动变成 `TEST456`
|
||||||
|
|
||||||
|
### 案例2:其他可能需要的场景
|
||||||
|
|
||||||
|
**航班号输入框**:
|
||||||
|
```kotlin
|
||||||
|
binding.flightNoInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
```
|
||||||
|
|
||||||
|
**运单号输入框**:
|
||||||
|
```kotlin
|
||||||
|
binding.waybillNoInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
```
|
||||||
|
|
||||||
|
**任何需要大写字母+数字的输入框**:
|
||||||
|
```kotlin
|
||||||
|
binding.anyInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
### 1. Import 路径
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 调用时机
|
||||||
|
|
||||||
|
必须在 View 初始化完成后调用,通常在 Activity 的 `initOnCreate` 或 Fragment 的 `onViewCreated` 中。
|
||||||
|
|
||||||
|
### 3. 与其他 Filter 组合使用
|
||||||
|
|
||||||
|
如果需要同时使用多个 Filter:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val filters = arrayOf(
|
||||||
|
UpperCaseAlphanumericInputFilter(),
|
||||||
|
InputFilter.LengthFilter(20) // 同时限制长度
|
||||||
|
)
|
||||||
|
editText.filters = filters
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 覆盖已有 Filter
|
||||||
|
|
||||||
|
调用 `setUpperCaseAlphanumericFilter()` 会覆盖已有的 Filter。如果需要保留原有 Filter,请手动组合:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val existingFilters = editText.filters
|
||||||
|
val newFilters = existingFilters + UpperCaseAlphanumericInputFilter()
|
||||||
|
editText.filters = newFilters
|
||||||
|
```
|
||||||
|
|
||||||
|
## 扩展建议
|
||||||
|
|
||||||
|
如果需要其他类型的输入过滤器,可以参考 `UpperCaseAlphanumericInputFilter` 的实现:
|
||||||
|
|
||||||
|
### 示例1:只允许数字
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
class DigitsOnlyInputFilter : InputFilter {
|
||||||
|
override fun filter(
|
||||||
|
source: CharSequence?,
|
||||||
|
start: Int,
|
||||||
|
end: Int,
|
||||||
|
dest: Spanned?,
|
||||||
|
dstart: Int,
|
||||||
|
dend: Int
|
||||||
|
): CharSequence? {
|
||||||
|
if (source.isNullOrEmpty()) return null
|
||||||
|
|
||||||
|
val filtered = StringBuilder()
|
||||||
|
for (i in start until end) {
|
||||||
|
val char = source[i]
|
||||||
|
if (char in '0'..'9') {
|
||||||
|
filtered.append(char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (filtered.toString() == source.subSequence(start, end).toString()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
filtered.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EditText.setDigitsOnlyFilter() {
|
||||||
|
this.filters = arrayOf(DigitsOnlyInputFilter())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例2:只允许小写字母和数字
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
class LowerCaseAlphanumericInputFilter : InputFilter {
|
||||||
|
override fun filter(
|
||||||
|
source: CharSequence?,
|
||||||
|
start: Int,
|
||||||
|
end: Int,
|
||||||
|
dest: Spanned?,
|
||||||
|
dstart: Int,
|
||||||
|
dend: Int
|
||||||
|
): CharSequence? {
|
||||||
|
if (source.isNullOrEmpty()) return null
|
||||||
|
|
||||||
|
val filtered = StringBuilder()
|
||||||
|
for (i in start until end) {
|
||||||
|
val char = source[i]
|
||||||
|
if (char in 'A'..'Z' || char in 'a'..'z' || char in '0'..'9') {
|
||||||
|
filtered.append(char.lowercaseChar())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (filtered.toString() == source.subSequence(start, end).toString()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
filtered.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun EditText.setLowerCaseAlphanumericFilter() {
|
||||||
|
this.filters = arrayOf(LowerCaseAlphanumericInputFilter())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试建议
|
||||||
|
|
||||||
|
在使用前建议测试以下场景:
|
||||||
|
|
||||||
|
1. 输入小写字母是否自动转大写
|
||||||
|
2. 输入中文是否被过滤
|
||||||
|
3. 输入特殊符号是否被过滤
|
||||||
|
4. 输入空格是否被过滤
|
||||||
|
5. 粘贴文本是否正确处理
|
||||||
|
6. 与软键盘的兼容性
|
||||||
|
|
||||||
|
## 相关文件
|
||||||
|
|
||||||
|
- **核心实现**: `module_base/src/main/java/com/lukouguoji/module_base/ktx/EditTextKtx.kt`
|
||||||
|
- **使用示例**: `module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcBoxWeighingAddActivity.kt`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**最后更新**: 2025-12-16
|
||||||
|
**维护人员**: 开发团队
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.lukouguoji.module_base.ktx
|
package com.lukouguoji.module_base.ktx
|
||||||
|
|
||||||
import android.text.InputFilter
|
import android.text.InputFilter
|
||||||
|
import android.text.Spanned
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.databinding.BindingAdapter
|
import androidx.databinding.BindingAdapter
|
||||||
|
|
||||||
@@ -12,4 +13,47 @@ fun setTextAllCaps(et: EditText, allCaps: Boolean) {
|
|||||||
} else {
|
} else {
|
||||||
et.filters = emptyArray<InputFilter>()
|
et.filters = emptyArray<InputFilter>()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 大写字母和数字输入过滤器
|
||||||
|
* 只允许输入大写字母(A-Z)和数字(0-9),小写字母自动转为大写
|
||||||
|
*/
|
||||||
|
class UpperCaseAlphanumericInputFilter : InputFilter {
|
||||||
|
override fun filter(
|
||||||
|
source: CharSequence?,
|
||||||
|
start: Int,
|
||||||
|
end: Int,
|
||||||
|
dest: Spanned?,
|
||||||
|
dstart: Int,
|
||||||
|
dend: Int
|
||||||
|
): CharSequence? {
|
||||||
|
if (source.isNullOrEmpty()) return null
|
||||||
|
|
||||||
|
val filtered = StringBuilder()
|
||||||
|
for (i in start until end) {
|
||||||
|
val char = source[i]
|
||||||
|
// 只允许ASCII字母(A-Z, a-z)和数字(0-9)
|
||||||
|
if (char in 'A'..'Z' || char in 'a'..'z' || char in '0'..'9') {
|
||||||
|
// 自动转为大写
|
||||||
|
filtered.append(char.uppercaseChar())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果过滤后的内容与原内容相同,返回null表示不修改
|
||||||
|
// 否则返回过滤后的内容
|
||||||
|
return if (filtered.toString() == source.subSequence(start, end).toString()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
filtered.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为 EditText 设置大写字母和数字输入过滤器
|
||||||
|
* 使用方式: editText.setUpperCaseAlphanumericFilter()
|
||||||
|
*/
|
||||||
|
fun EditText.setUpperCaseAlphanumericFilter() {
|
||||||
|
this.filters = arrayOf(UpperCaseAlphanumericInputFilter())
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import com.lukouguoji.gjc.R
|
|||||||
import com.lukouguoji.gjc.databinding.ActivityGjcBoxWeighingAddBinding
|
import com.lukouguoji.gjc.databinding.ActivityGjcBoxWeighingAddBinding
|
||||||
import com.lukouguoji.gjc.viewModel.GjcBoxWeighingAddViewModel
|
import com.lukouguoji.gjc.viewModel.GjcBoxWeighingAddViewModel
|
||||||
import com.lukouguoji.module_base.base.BaseBindingActivity
|
import com.lukouguoji.module_base.base.BaseBindingActivity
|
||||||
|
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港板箱过磅添加页面
|
* 国际出港板箱过磅添加页面
|
||||||
@@ -22,6 +23,11 @@ class GjcBoxWeighingAddActivity :
|
|||||||
setBackArrow("板箱过磅")
|
setBackArrow("板箱过磅")
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
viewModel.initOnCreated(this)
|
viewModel.initOnCreated(this)
|
||||||
|
|
||||||
|
// 为架子车号、ULD编码、IMP代码添加大写字母和数字的输入限制
|
||||||
|
binding.carIdInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
binding.uldNoInput.et.setUpperCaseAlphanumericFilter()
|
||||||
|
binding.impCodeInput.et.setUpperCaseAlphanumericFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -102,6 +102,7 @@
|
|||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
|
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
|
||||||
|
android:id="@+id/impCodeInput"
|
||||||
hint='@{"请输入IMP代码"}'
|
hint='@{"请输入IMP代码"}'
|
||||||
title='@{"IMP代码"}'
|
title='@{"IMP代码"}'
|
||||||
titleLength="@{5}"
|
titleLength="@{5}"
|
||||||
|
|||||||
Reference in New Issue
Block a user