Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Coroutines
- Rxjava
- TEST
- Coroutine
- Codeforces
- activity
- livedata
- ProGuard
- architecture
- Gradle
- 코루틴
- textfield
- 암호학
- 코드포스
- MyVoca
- MiTweet
- AWS
- GitHub
- android
- relay
- 백준
- boj
- 쿠링
- androidStudio
- pandas
- Hilt
- 프로그래머스
- Compose
- Kotlin
- Python
Archives
- Today
- Total
이동식 저장소
TextField에 default string을 줘도 커서가 맨 앞으로 가는 이유 본문
문제
초기 문자열이 있는 ``TextField``를 다음과 같이 선언하였다.
@LightPreview
@Composable
private fun TextFieldPreview() {
var textFieldValue by remember { mutableStateOf("검색하세요") }
KuringTheme {
TextField(
value = textFieldValue,
onValueChange = {
textFieldValue = it
}
)
}
}
프리뷰를 실행해 보면, 처음부터 문자열이 있음에도 불구하고(``검색하세요``) 커서가 맨 앞에 있는 모습을 확인할 수 있다. 실제로는 문자열의 맨 끝에 와야 자연스럽다.
원인
원인을 파악하기 위해 ``TextField``의 내부 구현을 뜯어보자.
우선, ``TextField``는 ``String``을 매개변수로 받는 오버로딩(이하 S)과, ``TextFieldValue``를 매개변수로 받는 오버로딩(이하 T)이 있다. S를 호출하면 S 내부에서 ``TextFieldValue``를 만들어서 T에 넘겨주는 방식이다.
그런데 ``TextFieldValue``의 생성자를 보면, 커서의 위치를 나타내는 ``selection``의 기본값이 ``TextRange.Zero``이다. 즉 명시적으로 값을 넘겨주지 않는 이상, 커서는 언제나 맨 앞에 위치한다는 것.
해결법?
따라서 커서의 위치를 문자열 맨 뒤로 옮기려면, ``TextFieldValue``의 selection 매개변수를 문자열 맨 뒤로 지정하여 ``TextField``에 넘겨줘야 한다.
@LightPreview
@Composable
private fun TextFieldPreview() {
val initialString = "검색하세요"
var textFieldValue by remember {
mutableStateOf(
TextFieldValue(
text = initialString,
selection = TextRange(initialString.length),
)
)
}
KuringTheme {
TextField(
value = textFieldValue,
onValueChange = {
textFieldValue = it
},
)
}
}
이론적으로는 위 코드를 실행하면 커서의 초기 위치가 맨 뒤여야 하지만, ``TextField``를 클릭하는 순간 selection의 값이 0으로 할당된다.
진짜 해결법
따라서 다음과 같이 맨 처음에만 새 ``TextFieldValue``의 업데이트를 막으면 된다.
@LightPreview
@Composable
private fun TextFieldPreview() {
val initialString = "검색하세요"
var textFieldValue by remember {
mutableStateOf(
TextFieldValue(
text = initialString,
selection = TextRange(initialString.length),
)
)
}
var isInitial by rememberSaveable { mutableStateOf(true) }
KuringTheme {
TextField(
value = textFieldValue,
onValueChange = {
if (!isInitial) {
textFieldValue = it
}
isInitial = false
},
)
Text(
text = textFieldValue.selection.toString(),
)
}
}
'Primary > Compose' 카테고리의 다른 글
Icon vs. Image (0) | 2024.04.07 |
---|---|
Compose에서 시스템 폰트 크기 확인하기 (0) | 2024.03.24 |
Compose에서 Icon의 크기를 IconButton만큼 키우고 싶다면? (0) | 2024.02.06 |
ViewModel에 너무 많은 책임을 지우지 말 것 (0) | 2024.02.04 |
Composable 매개변수 줄이기 - 오버로딩 활용 (3) | 2024.01.10 |
Comments