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

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

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

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

  1. TextField הוא ההטמעה של Material Design. מומלץ לבחור מיישום זה, כי הוא תואם ל-Material Design הנחיות:
    • סגנון ברירת המחדל מלא
    • 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 מרובה שורות, עם שתי שורות שניתנות לעריכה וגם התווית

אנחנו ממליצים על TextField על BasicTextField כשהעיצוב דורש חומר TextField או OutlineTextField. עם זאת, צריך להשתמש ב-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 אפשר להגדיר אפשרויות להגדרות המקלדת, כמו המקלדת פריסה, או להפעיל את התיקון האוטומטי אם הוא נתמך על ידי המקלדת. במידה מסוימת ייתכן שאין הבטחה כלשהי של אפשרויות, אם מקלדת התוכנה לא עומדת בדרישות של שמופיעות כאן. זוהי רשימת המקלדת הנתמכות options:

  • 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' }
        }
    )
}

כדי לקבוע את מיקום הסמן בזמן ניקוי הטקסט, משתמשים בסמל 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 בתור מקור האמת. מידע נוסף על המיקום שאליו יש להעלות את המדינה שלך זמין תיעוד של State hoisting.