Jetpack Compose自适应TextView: AutoSizeTextView

之前的文章Android Oreo--Autosizing TextViews自适应TextView介绍了Android 8.0的一个新特性文本字体大小自适应,是一个非常实用的工具,但是在Jetpack Compose却无法使用,本文就在Jetpack Compose中研究下怎么实现文本大小自适应。

先看下最终的效果:


demo.gif

直接上代码,不解释,因为不难理解:

AutoSizeTextView.kt

package com.zzh.eden.stark.demo.ui

import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.sp

@Composable
fun AutoSizeTextView(str: MutableState<String> = mutableStateOf(""), defaultSizeSp: Int = 15, maxLines: Int = 1) {
    var readyToDraw: Boolean by remember { mutableStateOf(false) }
    // var size = MaterialTheme.typography.bodyMedium
    // var tvStyle by remember { mutableStateOf(size) }
    var fontSize by remember { mutableStateOf(defaultSizeSp.sp) }
    Text(text = str.value,
        maxLines = maxLines,
        fontSize = fontSize,
        overflow = TextOverflow.Ellipsis,
        // style = tvStyle, // 这个方式也能动态调整字体大小,可以放开注释看下效果
        modifier = Modifier
            .drawWithContent {
                if (readyToDraw) drawContent()
            },
        onTextLayout = { textLayoutResult ->
            if (textLayoutResult.didOverflowHeight) {
                // 下面两行是两个方式,都可行
                // tvStyle = (tvStyle.copy(fontSize = tvStyle.fontSize * 0.95))
                fontSize = fontSize * 0.95
            } else {
                readyToDraw = true
            }
        }
    )
}

MainActivity.kt

package com.zzh.eden.stark.demo

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import com.zzh.eden.stark.demo.ui.AutoSizeTextView
import com.zzh.eden.stark.demo.ui.theme.StarkdemoTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            StarkdemoTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    delTest()
                }
            }
        }
    }

    @Composable
    fun delTest() {
        val context = LocalContext.current
        var clickCnt: MutableState<Int> = remember { mutableStateOf(0) }
        var text: MutableState<String> = remember { mutableStateOf("click cnt=${clickCnt}") }
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .fillMaxHeight(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Button(
                onClick = {
                    clickCnt.value += 1
                    StringBuilder().apply {
                        for (tmpI in 1..clickCnt.value) {
                            append("x")
                        }
                        text.value = "click cnt=${clickCnt}_${this}"
                    }
                }) {
                AutoSizeTextView(text)
            }
        }
    }
}






参考文献:

  1. android:autoSizeTextType in Jetpack Compose

  2. Jetpack compose AutoSizeText

  3. https://jetpackcompose.cn/docs/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容