טיפול בקלט של משתמשים

TextField מאפשר למשתמשים להזין טקסט ולשנות אותו. בדף הזה נסביר איך מטמיעים את TextField, מעצבים את הקלט של TextField ומגדירים אפשרויות אחרות של TextField, כמו אפשרויות מקלדת וטרנספורמציה חזותית של קלט המשתמש.

בחירת הטמעה של TextField

יש שתי רמות של הטמעת TextField:

  1. TextField הוא ההטמעה של Material Design. מומלץ לבחור מיישום זה, כי הוא תואם ל-Material Design הנחיות:
    • עיצוב ברירת המחדל הוא filled
    • OutlinedTextField היא הגרסה של הסגנון outline
  2. BasicTextField מאפשר למשתמשים לערוך טקסט באמצעות מקלדת חומרה או תוכנה, אבל לא מספק קישוטים כמו רמז או placeholder.

@Composable
fun SimpleFilledTextFieldSample() {
    var text by remember { mutableStateOf("Hello") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

שדה טקסט שניתן לעריכה שמכיל את המילה

@Composable
fun SimpleOutlinedTextFieldSample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

שדה טקסט שניתן לעריכה, עם מסגרת ותווית סגולות.

סגנון TextField

ל-TextField ול-BasicTextField יש הרבה פרמטרים משותפים להתאמה אישית. הרשימה המלאה של TextField זמינה במקור TextField . זוהי רשימה חלקית של חלק מהפרמטרים השימושיים:

  • singleLine
  • maxLines
  • textStyle

@Composable
fun StyledTextField() {
    var value by remember { mutableStateOf("Hello\nWorld\nInvisible") }

    TextField(
        value = value,
        onValueChange = { value = it },
        label = { Text("Enter text") },
        maxLines = 2,
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(20.dp)
    )
}

שדה טקסט עם כמה שורות, עם שתי שורות שניתן לערוך וגם התווית

מומלץ להשתמש ב-TextField במקום ב-BasicTextField כשהעיצוב דורש חומר TextField או OutlinedTextField. עם זאת, צריך להשתמש ב-BasicTextField כאשר בונים עיצובים שלא זקוקים לקישוטים מהמפרט Material.

קלט סגנון באמצעות Brush API

אפשר להשתמש ב-Brush API כדי ליצור עיצוב מתקדם יותר ב-TextField. בקטע הבא מוסבר איך להשתמש במברשת כדי להוסיף הדרגתי של צבע לקלט TextField.

מידע נוסף על שימוש ב-Brush API כדי לעצב טקסט זמין במאמר הפעלת עיצוב מתקדם באמצעות Brush API.

הטמעת הדרגתיות של צבעים באמצעות TextStyle

כדי להטמיע הדרגתי צבעוני תוך כדי הקלדה בתוך TextField, צריך להגדיר את המברשת נבחר כ-TextStyle עבור TextField שלך. בדוגמה הזו אנחנו משתמשים במברשת מובנית עם linearGradient כדי להציג את אפקט הדרגתיות של קשת בזמן הקלדה של טקסט ב-TextField.

var text by remember { mutableStateOf("") }
val brush = remember {
    Brush.linearGradient(
        colors = rainbowColors
    )
}
TextField(
    value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush)
)

שימוש ב-buildAnnotatedString וב-SpanStyle, יחד עם LinearGradient, כדי להתאים אישית רק קטע טקסט.
איור 3. באמצעות buildAnnotatedString ו-SpanStyle, יחד עם linearGradient, להתאמה אישית רק של קטע טקסט.

הגדרת אפשרויות המקלדת

באמצעות TextField אפשר להגדיר אפשרויות להגדרות המקלדת, כמו המקלדת פריסה, או להפעיל את התיקון האוטומטי אם הוא נתמך על ידי המקלדת. במידה מסוימת ייתכן שאין הבטחה כלשהי של אפשרויות, אם מקלדת התוכנה לא עומדת בדרישות של שמופיעות כאן. זוהי רשימת אפשרויות המקלדת הנתמכות:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

פורמט הקלט

TextField מאפשר לך להגדיר VisualTransformation בערך הקלט, למשל החלפת תווים ב-* בשביל סיסמאות, או הוספת מקפים כל 4 ספרות למספר כרטיס האשראי:

@Composable
fun PasswordTextField() {
    var password by rememberSaveable { mutableStateOf("") }

    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Enter password") },
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
    )
}

שדה להזנת טקסט של סיסמה, שבו הטקסט מוסתר

דוגמאות נוספות זמינות בקוד המקור VisualTransformationSamples.

קלט נקי

משימה נפוצה בעריכת טקסט היא להסיר תווים מובילים, או לשנות את מחרוזת הקלט בכל פעם שהיא משתנה.

כמודל, עליך להניח שהמקלדת עשויה לבצע שינויים שרירותיים וגדולים יערוך כל onValueChange. מצב כזה יכול לקרות, למשל, אם המשתמש משתמש בתיקון אוטומטי, מחליף מילה באמוג'י או משתמש בתכונות עריכה חכמות אחרות. שפת תרגום צריך לכתוב כל לוגיקה של טרנספורמציה מתוך הנחה הטקסט הנוכחי שמועבר אל onValueChange לא קשור לטקסט הקודם או הבא שיועברו אל onValueChange.

כדי להטמיע שדה טקסט שלא מאפשר אפסים בתחילת מספר, אפשר לעשות זאת כך: הסרת כל האפסים בתחילת כל שינוי בערך.

@Composable
fun NoLeadingZeroes() {
    var input by rememberSaveable { mutableStateOf("") }
    TextField(
        value = input,
        onValueChange = { newText ->
            input = newText.trimStart { it == '0' }
        }
    )
}

כדי לשלוט במיקום הסמן בזמן ניקוי הטקסט, משתמשים ב-overload‏ TextFieldValue של TextField כחלק מהמצב.

שיטות מומלצות לעבודה עם מצב

בהמשך מפורטות שיטות מומלצות להגדרה ולעדכון המצב של TextField כדי למנוע בעיות קלט באפליקציה.

  • שימוש ב-MutableState כדי לייצג את המצב של TextField: מומלץ להימנע משימוש בזרמים תגובתיים כמו StateFlow כדי לייצג את המצב של TextField, כי המבנים האלה עלולים לגרום לעיכובים אסינכרונים.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • מניעת עיכובים בעדכון המדינה: כשמתקשרים אל onValueChange, מעדכנים את TextField באופן סינכרוני ומיידי:

// SignUpViewModel.kt

class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {

    var username by mutableStateOf("")
        private set

    fun updateUsername(input: String) {
        username = input
    }
}

// SignUpScreen.kt

@Composable
fun SignUpScreen(/*...*/) {

    OutlinedTextField(
        value = viewModel.username,
        onValueChange = { username -> viewModel.updateUsername(username) }
        /*...*/
    )
}

  • איפה מגדירים את המדינה (State): אם נדרש עסק במדינה TextField ואימותים לוגיים תוך כדי הקלדה, נכון להעלות את המצב ViewModel אם לא, אפשר להשתמש בתכנים קומפוזביליים או ב-State holder בתור מקור האמת. למידע נוסף על המיקום שבו צריך להעלות את המצב, עיינו במאמר בנושא העלאת המצב.

אין המלצות כרגע.

אפשר לנסות לחשבון Google.