개요
Android Jetpack Compose에서 비밀번호 입력 필드를 구현할 때, 입력된 텍스트를 숨기기 위해 visualTransformation을 설정해야 합니다. 기본적으로 PasswordVisualTransformation()을 사용하면 입력된 문자 대신 •(블릿) 문자가 표시됩니다. 또한, BasicTextField에서는 직접 decorationBox를 활용해 UI를 구성해야 합니다.
이 가이드에서는 TextField와 BasicTextField에서 비밀번호 입력을 처리하는 방법과, visualTransformation을 활용한 비밀번호 가리기 및 표시 기능을 구현하는 방법을 설명합니다.
1. TextField에서 비밀번호 입력 처리 (PasswordVisualTransformation 사용)
TextField는 기본적으로 visualTransformation을 설정하면 비밀번호를 가릴 수 있으며, trailingIcon을 추가해 비밀번호 표시/숨김 기능을 제공할 수 있습니다.
📌 코드 예제
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
@Composable
fun PasswordTextField() {
var password by remember { mutableStateOf("") }
var isPasswordVisible by remember { mutableStateOf(false) }
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = { Text("비밀번호") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
IconButton(onClick = { isPasswordVisible = !isPasswordVisible }) {
Icon(
imageVector = if (isPasswordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff,
contentDescription = if (isPasswordVisible) "비밀번호 숨기기" else "비밀번호 보기"
)
}
}
)
}
🔍 코드 설명
- visualTransformation 적용
- PasswordVisualTransformation()을 사용하면 비밀번호가 • 문자로 표시됩니다.
- VisualTransformation.None을 적용하면 원래 입력된 텍스트가 보입니다.
- 비밀번호 표시/숨기기 버튼 추가
- trailingIcon에 IconButton을 추가하여 비밀번호 가리기/보이기 기능을 구현했습니다.
- Icons.Default.Visibility 및 Icons.Default.VisibilityOff 아이콘을 사용하여 UI를 개선했습니다.
2. BasicTextField에서 비밀번호 입력 처리 (visualTransformation 적용)
BasicTextField는 TextField보다 기본 제공 기능이 적어 decorationBox를 활용하여 UI를 직접 커스텀해야 합니다.
📌 코드 예제
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
@Composable
fun BasicPasswordTextField() {
var password by remember { mutableStateOf("") }
var isPasswordVisible by remember { mutableStateOf(false) }
Column(modifier = Modifier.padding(16.dp)) {
BasicTextField(
value = password,
onValueChange = { password = it },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(),
decorationBox = { innerTextField ->
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = { Text("비밀번호") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(),
trailingIcon = {
IconButton(onClick = { isPasswordVisible = !isPasswordVisible }) {
Icon(
imageVector = if (isPasswordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff,
contentDescription = if (isPasswordVisible) "비밀번호 숨기기" else "비밀번호 보기"
)
}
},
singleLine = true
)
}
)
}
}
🔍 코드 설명
- decorationBox를 활용한 UI 구성
- BasicTextField는 기본 UI 요소가 없어 OutlinedTextField를 decorationBox 내부에서 사용하여 UI를 구성했습니다.
- 비밀번호 표시/숨기기 기능 적용
- visualTransformation을 PasswordVisualTransformation()으로 설정하여 입력값을 가렸습니다.
- trailingIcon을 추가하여 비밀번호 표시/숨기기 기능을 제공했습니다.
3. visualTransformation을 커스텀하여 비밀번호 가리기 (CustomPasswordVisualTransformation)
기본 PasswordVisualTransformation()을 사용하지 않고, 특정 문자(* 등)로 비밀번호를 가릴 수도 있습니다.
📌 코드 예제
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.OffsetMapping
import androidx.compose.ui.text.input.VisualTransformation
class CustomPasswordVisualTransformation(private val maskChar: Char = '*') : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
val maskedText = maskChar.toString().repeat(text.length)
return TransformedText(
AnnotatedString(maskedText),
OffsetMapping.Identity
)
}
}
📌 사용 예제
TextField(
value = password,
onValueChange = { password = it },
label = { Text("비밀번호") },
visualTransformation = CustomPasswordVisualTransformation('*')
)
🔍 코드 설명
- CustomPasswordVisualTransformation('*')을 사용하여 입력된 모든 문자를 *로 변환했습니다.
- OffsetMapping.Identity를 사용하여 입력된 문자의 길이를 유지했습니다.
- 이 방식을 사용하면 다양한 문자(•, #, _ 등)로 비밀번호를 표시할 수 있습니다.
4. 요약 및 결론
기능 | TextField | BasicTextField |
비밀번호 가리기 | PasswordVisualTransformation() 사용 | visualTransformation을 적용해야 함 |
비밀번호 표시/숨기기 | trailingIcon으로 구현 가능 | decorationBox를 사용하여 직접 UI 구성 |
커스텀 마스킹 | CustomPasswordVisualTransformation('*') 사용 가능 | CustomPasswordVisualTransformation('*') 사용 가능 |
✔ 결론
- TextField는 visualTransformation 속성을 바로 적용할 수 있어 간단하게 비밀번호 필드를 구현할 수 있습니다.
- BasicTextField는 UI를 직접 커스텀해야 하지만, 보다 자유로운 디자인이 가능합니다.
- CustomPasswordVisualTransformation을 활용하면 기본 • 대신 *, _ 등의 문자로 가릴 수도 있습니다.
Jetpack Compose에서 비밀번호 입력 필드를 구현할 때 위 방법을 활용하면 사용자 경험(UX)과 보안성을 높일 수 있습니다. 🚀
사용후기
CustomPasswordVisualTransformation 으로 사용시에 텍스트로만 적용 가능한점이 아쉬웠고
기본으로 사용하고 있는 • 이 너무 딱붙어보여서 커스텀해서 공백을 추가해서 사용함!
