주어진 영역에 딱 맞게 텍스트 크기를 조절하고 싶을 때 사용하는 기능
원본 영상을 참고했습니다.
@Composable
fun ResizeText(
modifier: Modifier = Modifier,
style: TextStyle = MaterialTheme.typography.labelSmall,
text: String
) {
var resizedTextStyle by remember {
mutableStateOf(style)
}
var shouldDraw by remember {
mutableStateOf(false)
}
val defaultFontSize = MaterialTheme.typography.labelSmall.fontSize
Text(
modifier = modifier
.drawWithContent {
if (shouldDraw) {
drawContent()
}
},
text = text,
style = resizedTextStyle,
softWrap = false,
onTextLayout = { result ->
if (result.didOverflowWidth) {
if (style.fontSize.isUnspecified) {
resizedTextStyle = resizedTextStyle.copy(
fontSize = defaultFontSize
)
}
resizedTextStyle = resizedTextStyle.copy(
fontSize = resizedTextStyle.fontSize * 0.95
)
} else {
shouldDraw = true
}
}
)
}
텍스트에 적용할 스타일을 저장. 기본은 입력으로 받은 스타일
var resizedTextStyle by remember {
mutableStateOf(style)
}
크기가 완전히 정해졌는지 검사하는 변수
사실 없어도 되는데 이게 없으면 숫자가 줄어드는 걸 사용자가 보게된다.
숫자가 줄어드는 게 이상하면 크기가 고정됐을 때만 보여주게 이걸 추가해야 한다.
var shouldDraw by remember {
mutableStateOf(false)
}
...
modifier.drawWithContent {
if (shouldDraw) {
drawContent()
}
}
텍스트가 이상한 값이 된 경우, 기본으로 사용할 크기
그냥 Sp 타입을 사용해도 된다.
val defaultFontSize = MaterialTheme.typography.labelSmall.fontSize
...
if (style.fontSize.isUnspecified) {
resizedTextStyle = resizedTextStyle.copy(
fontSize = defaultFontSize
)
}
Text는 기본적으로 텍스트가 주어진 영역보다 크면 자동으로 줄바꿈을 해버린다.
해당 옵션이 켜져있으면 기능이 적용되지 않아서 꺼야 한다.
softWrap = false
여기서는 텍스트가 너비를 벗어났는지만 검사했는데 높이도 검사할 수 있다.
if (result.didOverflowWidth)
텍스트 크기를 영역에 맞을 때 까지 줄이는 코드
여기서는 0.95%로 줄였지만 다른 수치를 사용해도 된다.
resizedTextStyle = resizedTextStyle.copy(
fontSize = resizedTextStyle.fontSize * 0.95
)