首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Jetpack Compose中屏蔽TextField以显示dd/mm/yyyy日期格式?

如何在Jetpack Compose中屏蔽TextField以显示dd/mm/yyyy日期格式?
EN

Stack Overflow用户
提问于 2021-09-24 05:09:56
回答 1查看 788关注 0票数 0

使用Jetpack Compose,我如何格式化TextField值以遵循"dd/mm/yyyy“格式?

EN

回答 1

Stack Overflow用户

发布于 2021-09-24 05:09:56

更新的答案

可以接受Jetpack Compose TextField任何类型掩码的VisualTranformation实现:

代码语言:javascript
运行
复制
class MaskVisualTransformation(private val mask: String) : VisualTransformation {

    private val specialSymbolsIndices = mask.indices.filter { mask[it] != '#' }

    override fun filter(text: AnnotatedString): TransformedText {
        var out = ""
        var maskIndex = 0
        text.forEach { char ->
            while (specialSymbolsIndices.contains(maskIndex)) {
                out += mask[maskIndex]
                maskIndex++
            }
            out += char
            maskIndex++
        }
        return TransformedText(AnnotatedString(out), offsetTranslator())
    }

    private fun offsetTranslator() = object : OffsetMapping {
        override fun originalToTransformed(offset: Int): Int {
            val offsetValue = offset.absoluteValue
            if (offsetValue == 0) return 0
            var numberOfHashtags = 0
            val masked = mask.takeWhile {
                if (it == '#') numberOfHashtags++
                numberOfHashtags < offsetValue
            }
            return masked.length + 1
        }

        override fun transformedToOriginal(offset: Int): Int {
            return mask.take(offset.absoluteValue).count { it == '#' }
        }
    }
}

使用方法:

代码语言:javascript
运行
复制
@Composable
fun DateTextField() {
    var date by remember { mutableStateOf("") }
    TextField(
        value = date,
        onValueChange = {
            if (it.length <= DATE_LENGTH) {
                date = it
            }
        },
        visualTransformation = MaskVisualTransformation(DATE_MASK)
    )
}

object DateDefaults {
    const val DATE_MASK = "##/##/####"
    const val DATE_LENGTH = 8 // Equals to "##/##/####".count { it == '#' }
}

老答案

就像Jetpack Compose提供了密码的可视化转换一样,我们也可以进行自己的可视化转换。

代码语言:javascript
运行
复制
class DateTransformation : VisualTransformation {

    // XX/XX/XXXX format
    override fun filter(text: AnnotatedString): TransformedText {
        var out = ""
        text.text.forEachIndexed { index, char ->
            when (index) {
                2 -> out += "/$char"
                4 -> out += "/$char"
                else -> out += char
            }
        }
        val numberOffsetTranslator = object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                if (offset <= 2) return offset
                if (offset <= 4) return offset + 1
                return offset + 2
            }

            override fun transformedToOriginal(offset: Int): Int {
                if (offset <= 2) return offset
                if (offset <= 5) return offset - 1
                return offset - 2
            }
        }
        return TransformedText(AnnotatedString(out), numberOffsetTranslator)
    }
}

我们返回一个应用了过滤器的TransformedText和一个在原始文本和转换后的文本之间进行转换的OffsetMapping。

现在,我们可以在任何TextField中使用我们的Visual Transformation类。

代码语言:javascript
运行
复制
var text by remember { mutableStateOf("") }
TextField(
    value = text,
    visualTransformation = DateTransformation(),
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
    onValueChange = {
        if (it.length < 9) text = it
    }
)
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69309829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档