반응형
안드로이드에서 글자의 길이가 길고 TextView의 크기를 제한되어 있을때,
글자의 크기를 줄여서 보여줄때가 있다.
Compose에서 기본으로 사용할 수 있는 기능이 없어 구글링하여 커스텀 AutoResizeText를 찾았다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun AutoResizeText( | |
text: String, | |
fontSizeRange: FontSizeRange, | |
modifier: Modifier = Modifier, | |
color: Color = Color.Unspecified, | |
fontStyle: FontStyle? = null, | |
fontWeight: FontWeight? = null, | |
fontFamily: FontFamily? = null, | |
letterSpacing: TextUnit = TextUnit.Unspecified, | |
textDecoration: TextDecoration? = null, | |
textAlign: TextAlign? = null, | |
lineHeight: TextUnit = TextUnit.Unspecified, | |
overflow: TextOverflow = TextOverflow.Clip, | |
softWrap: Boolean = true, | |
maxLines: Int = Int.MAX_VALUE, | |
style: TextStyle = LocalTextStyle.current, | |
) { | |
var fontSizeValue by remember { mutableStateOf(fontSizeRange.max.value) } | |
var readyToDraw by remember { mutableStateOf(false) } | |
Text( | |
text = text, | |
color = color, | |
maxLines = maxLines, | |
fontStyle = fontStyle, | |
fontWeight = fontWeight, | |
fontFamily = fontFamily, | |
letterSpacing = letterSpacing, | |
textDecoration = textDecoration, | |
textAlign = textAlign, | |
lineHeight = lineHeight, | |
overflow = overflow, | |
softWrap = softWrap, | |
style = style, | |
fontSize = fontSizeValue.sp, | |
onTextLayout = { | |
if (it.didOverflowHeight && !readyToDraw) { | |
val nextFontSizeValue = fontSizeValue - fontSizeRange.step.value | |
if (nextFontSizeValue <= fontSizeRange.min.value) { | |
// Reached minimum, set minimum font size and it's readToDraw | |
fontSizeValue = fontSizeRange.min.value | |
readyToDraw = true | |
} else { | |
// Text doesn't fit yet and haven't reached minimum text range, keep decreasing | |
fontSizeValue = nextFontSizeValue | |
} | |
} else { | |
// Text fits before reaching the minimum, it's readyToDraw | |
readyToDraw = true | |
} | |
}, | |
modifier = modifier.drawWithContent { if (readyToDraw) drawContent() } | |
) | |
} | |
data class FontSizeRange( | |
val min: TextUnit, | |
val max: TextUnit, | |
val step: TextUnit = DEFAULT_TEXT_STEP, | |
) { | |
init { | |
require(min < max) { "min should be less than max, $this" } | |
require(step.value > 0) { "step should be greater than 0, $this" } | |
} | |
companion object { | |
private val DEFAULT_TEXT_STEP = 1.sp | |
} |
사용 방법은 다음과 같다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun Test(){ | |
Column( | |
Modifier.fillMaxSize() | |
) { | |
AutoResizeText( | |
text = "Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text Your Text 마지막임!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ", | |
color = Color.White, | |
modifier = Modifier | |
.fillMaxWidth() | |
.height(40.dp) | |
.background(Color.Blue), | |
fontSizeRange = FontSizeRange( | |
min = 18.sp, | |
max = 16.sp, | |
), | |
overflow = TextOverflow.Ellipsis, | |
style = MaterialTheme.typography.body1, | |
) | |
} | |
} |
참고로, Preview 화면에서는 동작하지 않으니 에뮬레이터나 실기기로 테스트하시길 바랍니다.
반응형
'안드로이드 > Jetpack Compose' 카테고리의 다른 글
[안드로이드 Compose] Button (0) | 2022.04.24 |
---|---|
[안드로이드 Compose] 버튼 Custom Shadow (0) | 2022.04.24 |
[안드로이드] Compose - LazyColmn (0) | 2022.04.22 |
[안드로이드] Compose - Scaffold, Row, Column (0) | 2022.04.21 |