# 大写字母数字输入过滤器使用指南

## 功能说明

为 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
**维护人员**: 开发团队
