查找最大字符可以适合一行Android JetPack撰写文本

发布于 2025-02-09 02:33:19 字数 207 浏览 3 评论 0原文

我想找到可以适合一行的字符总数 当前的JetPack组成文本

我可以获取此信息的任何字段。谢谢

I want to find the total number of characters that can fit in one line of a current Jetpack compose Text

Any field where I can get this information. Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

潜移默化 2025-02-16 02:33:19

有可能在打印文本宽度之前计算文本宽度,请参阅 [1] [2]

Column {

    var size by remember { mutableStateOf(IntSize.Zero) }
    val textMeasurer = rememberTextMeasurer()
    val longText = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
    val shortText = getShortenedText(longText, textMeasurer, size.width)

    Text(
        modifier = Modifier
            .fillMaxWidth()
            .onSizeChanged { size = it },
        text = shortText,
        maxLines = 1,
        style = yourStyle,
    )

在这种情况下,我们可以根据需要测量简化的文本,直到获得适合text的字符串为止。首先,我们将测量longText的全长。如果它适合文本,我们将打印它。如果不合适,我们将减少文本并再次测量。您可以按照自己的意愿进行二进制搜索或按比例分配。

@Composable
private fun getShortenedText(
    longText: String,
    textMeasurer: TextMeasurer,
    maxWidth: Int,
): String {
    if (maxWidth == 0) return ""

    var start = 0
    var end = longText.length
    var text = longText.substring(0, end)
    var width = textMeasurer.measure(text, yourStyle).size.width
    if (width <= maxWidth) return text

    while (start < end - 1) {
        val newBorder = start + (end - start) / 2
        text = longText.substring(0, newBorder)
        width = textMeasurer.measure(text, yourStyle).size.width
        if (width <= maxWidth) {
            start = newBorder
        } else {
            end = newBorder
        }
    }

    return longText.substring(0, start)
}

如果您有多行文本,并且想适合几行(例如,不超过2行),则可以使用此方法。

只需在文本中替换maxlines = 1,然后添加此功能:

@Composable
private fun getLinesCount(
    text: String,
    maxWidth: Int,
    density: Density,
    fontFamilyResolver: FontFamily.Resolver,
): Int {
    val paragraph = Paragraph(
        text = text,
        style = yourStyle,
        constraints = Constraints(maxWidth = maxWidth),
        density = density,
        fontFamilyResolver = fontFamilyResolver,
    )
    return paragraph.lineCount
}

而不是接收宽度,而是获得行计数:

val density = LocalDensity.current
val fontFamilyResolver = LocalFontFamilyResolver.current
var linesCount = getLinesCount(text, maxWidth, density, fontFamilyResolver)

并检查它们:

if (linesCount <= 2) ...

There is a possibility to calculate text width before it will be printed, see [1] or [2].

Column {

    var size by remember { mutableStateOf(IntSize.Zero) }
    val textMeasurer = rememberTextMeasurer()
    val longText = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
    val shortText = getShortenedText(longText, textMeasurer, size.width)

    Text(
        modifier = Modifier
            .fillMaxWidth()
            .onSizeChanged { size = it },
        text = shortText,
        maxLines = 1,
        style = yourStyle,
    )

In this case we can measure a reduced text as many times as we want, until we get a string that will fit inside a Text. First we will measure a full length of a longText. If it fits into Text, we will print it. If it doesn't fit, we will reduce a text and measure again. You can use binary search or divide proportionally, as you wish.

@Composable
private fun getShortenedText(
    longText: String,
    textMeasurer: TextMeasurer,
    maxWidth: Int,
): String {
    if (maxWidth == 0) return ""

    var start = 0
    var end = longText.length
    var text = longText.substring(0, end)
    var width = textMeasurer.measure(text, yourStyle).size.width
    if (width <= maxWidth) return text

    while (start < end - 1) {
        val newBorder = start + (end - start) / 2
        text = longText.substring(0, newBorder)
        width = textMeasurer.measure(text, yourStyle).size.width
        if (width <= maxWidth) {
            start = newBorder
        } else {
            end = newBorder
        }
    }

    return longText.substring(0, start)
}

If you have multiline text and want to fit in several lines (for instance, not more than 2 lines), you can use this method.

Just replace maxLines = 1 in Text, then add this function:

@Composable
private fun getLinesCount(
    text: String,
    maxWidth: Int,
    density: Density,
    fontFamilyResolver: FontFamily.Resolver,
): Int {
    val paragraph = Paragraph(
        text = text,
        style = yourStyle,
        constraints = Constraints(maxWidth = maxWidth),
        density = density,
        fontFamilyResolver = fontFamilyResolver,
    )
    return paragraph.lineCount
}

Instead of receiving width, get lines count:

val density = LocalDensity.current
val fontFamilyResolver = LocalFontFamilyResolver.current
var linesCount = getLinesCount(text, maxWidth, density, fontFamilyResolver)

And check them:

if (linesCount <= 2) ...
千紇 2025-02-16 02:33:19

您可能假设text()合并是具有固定尺寸的某些占位符(框)

“在此处输入图像说明”

然后您将一些文本放入其中

​我们,您可以使用多少个角色来适合这个占位符。

但是事情以其他方式工作:

  1. 没有text() Composable 没有文本字符串。
  2. 尽可能多的空间。

text()可综合的占用 尽管文本仅由1个字符组成

您可能想解决一件事,但请问我们另一件事 - 请参阅什么是XY问题?可能是什么?编辑您的问题。

You probably assume that the Text() composable is some placeholder (box) with fixed dimensions

enter image description here

then you place some text into it

enter image description here

and ask us, how many characters you may use to fit this placeholder.

But things work the other way:

  1. There is no Text() composable without text string in it.
  2. The Text() composable occupy as much space, as it can.

So, for example, it occupies the whole screen, if there are no other elements, in spite of the text consist only of 1 character.

So your question in its current form has no sense.

You probably wanted to solve one thing, but ask us about the other – see What is the X-Y problem? and possibly edit your question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文