הגדרת שדות טקסט

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

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

Feature

שדות טקסט מבוססי-ערך

שדות טקסט מבוססי-מצב

הטבה לפי מדינה

ניהול מצב

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

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

  • הוסר ה-callback‏ onValueChange, ולכן אי אפשר להוסיף התנהגויות אסינכרוניות.
  • המצב נשמר גם אחרי הרכבה מחדש, הגדרה וסיום התהליך.

טרנספורמציה חזותית

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

משתמשים ב-InputTransformation כדי לשנות את הקלט של המשתמש לפני שהוא נשמר במצב, וב-OutputTransformation כדי לעצב את התוכן של שדה הטקסט בלי לשנות את נתוני המצב הבסיסיים.

  • אין יותר צורך לספק את מיפוי ההיסט בין הטקסט הגולמי המקורי לבין הטקסט שעבר טרנספורמציה באמצעות OutputTransformation.

מגבלות על שורות

אפשר להשתמש בערכים singleLine: Boolean, maxLines: Int ו-minLines: Int כדי לשלוט במספר השורות.

המאפיין lineLimits: TextFieldLineLimits משמש להגדרת מספר השורות המינימלי והמקסימלי ששדה הטקסט יכול לתפוס.

  • הפרמטר lineLimits מסוג TextFieldLineLimits מסיר את העמימות כשמגדירים מגבלות על שורות.

שדה טקסט מאובטח

לא רלוונטי

‫SecureTextField הוא קומפוזבילי שמבוסס על שדות טקסט מבוססי-מצב לכתיבת שדה סיסמה.

  • מאפשרת לבצע אופטימיזציה של האבטחה מתחת לפני השטח, ומגיעה עם ממשק משתמש מוגדר מראש עם textObfuscationMode.

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

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

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

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

TextField(
    state = rememberTextFieldState(initialText = "Hello"),
    label = { Text("Label") }
)

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

OutlinedTextField(
    state = rememberTextFieldState(),
    label = { Text("Label") }
)

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

סגנון TextField

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

  • textStyle
  • lineLimits

TextField(
    state = rememberTextFieldState("Hello\nWorld\nInvisible"),
    lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2),
    placeholder = { Text("") },
    textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
    label = { Text("Enter text") },
    modifier = Modifier.padding(20.dp)
)

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

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

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

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

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

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

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

val brush = remember {
    Brush.linearGradient(
        colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta)
    )
}
TextField(
    state = rememberTextFieldState(), textStyle = TextStyle(brush = brush)
)

טקסט שמוקלד בשדה טקסט, עם אפקט של מעבר צבעים בצבעי הקשת.
איור 1. אפקט של מעבר צבעים בצבעי הקשת לתוכן TextField.

ניהול המצב של שדה טקסט

‫TextField משתמש במחזיק מצב ייעודי שנקרא TextFieldState בשביל התוכן והבחירה שלו. TextFieldState מיועד להפעלה בכל מקום שמתאים לארכיטקטורה שלכם. יש 2 מאפיינים עיקריים שמופיעים ב-TextFieldState:

  • ‫initialText: התוכן של TextField.
  • ‫initialSelection: מציין את המיקום של הסמן או הבחירה.

מה שמבדיל בין TextFieldState לבין גישות אחרות, כמו הקריאה החוזרת (callback) onValueChange, הוא ש-TextFieldState מכיל באופן מלא את כל זרימת הקלט. זה כולל שימוש במבני נתונים נכונים, שימוש במסננים ובמעצבים מוטבעים וגם סנכרון של כל העריכות שמגיעות ממקורות שונים.

אפשר להשתמש ב-TextFieldState() כדי להעביר את המצב ב-TextField. לשם כך, מומלץ להשתמש בפונקציה rememberTextFieldState(). ‫rememberTextFieldState() יוצר את המופע TextFieldState בפונקציה קומפוזבילית, מוודא שערך דינמי נשמר בזיכרון ומספק פונקציונליות מובנית של שמירה ושחזור:

val usernameState = rememberTextFieldState()
TextField(
    state = usernameState,
    lineLimits = TextFieldLineLimits.SingleLine,
    placeholder = { Text("Enter Username") }
)

‫rememberTextFieldState יכול להיות פרמטר ריק או ערך התחלתי שמועבר כדי לייצג את ערך הטקסט בזמן האתחול. אם ערך אחר מועבר בהרכבה מחדש בהמשך, ערך המצב לא מתעדכן. כדי לעדכן את המצב אחרי שהוא מאותחל, קוראים לשיטות עריכה ב-TextFieldState.

TextField(
    state = rememberTextFieldState(initialText = "Username"),
    lineLimits = TextFieldLineLimits.SingleLine,
)

רכיב TextField עם הטקסט Username שמופיע בתוך שדה הטקסט.
איור 2. ‫TextField עם 'שם משתמש' כטקסט הראשוני.

שינוי הטקסט באמצעות TextFieldBuffer

‫TextFieldBuffer משמש כקונטיינר טקסט שניתן לעריכה, בדומה לStringBuilder. היא מכילה גם את תוכן הטקסט וגם מידע על הבחירה.

לרוב נתקלים ב-TextFieldBuffer כהיקף של מקבל בפונקציות כמו TextFieldState.edit,‏ InputTransformation.transformInput או OutputTransformation.transformOutput. בפונקציות האלה אפשר לקרוא או לעדכן את TextFieldBuffer לפי הצורך. לאחר מכן, השינויים האלה מועברים ל-TextFieldState או לצינור העיבוד במקרה של OutputTransformation.

אתם יכולים להשתמש בפונקציות עריכה רגילות כמו append, insert, replace או delete כדי לשנות את התוכן של המאגר. כדי לשנות את מצב הבחירה, אפשר להגדיר ישירות את המשתנה selection: TextRange או להשתמש בפונקציות עזר כמו placeCursorAtEnd או selectAll. הבחירה עצמה מיוצגת על ידי TextRange, כאשר אינדקס ההתחלה כלול ואינדקס הסיום לא כלול. הסימן TextRange עם ערכי התחלה וסיום זהים, כמו (3, 3), מציין מיקום סמן ללא תווים שנבחרו.

val phoneNumberState = rememberTextFieldState("1234567890")

TextField(
    state = phoneNumberState,
    keyboardOptions = KeyboardOptions(
        keyboardType = KeyboardType.Phone
    ),
    inputTransformation = InputTransformation.maxLength(10).then {
        if (!asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    },
    outputTransformation = OutputTransformation {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
)

עריכת הטקסט ב-TextFieldState

יש כמה שיטות שמאפשרות לערוך את המצב ישירות דרך משתנה המצב:

  • ‫edit: מאפשר לערוך את תוכן המצב ומספק TextFieldBuffer פונקציות כדי שתוכלו להשתמש בשיטות כמו insert,‏ replace,‏ append ועוד.

    // Initial textFieldState text passed in is "I love Android"
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    textFieldState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    textFieldState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • ‫setTextAndPlaceCursorAtEnd: מוחק את הטקסט הנוכחי, מחליף אותו בטקסט שצוין ומציב את הסמן בסוף.

    textFieldState.setTextAndPlaceCursorAtEnd("I really love Android")
    // textFieldState.text : I really love Android
    // textFieldState.selection : TextRange(21, 21)

  • ‫clearText: מחיקת כל הטקסט.

    textFieldState.clearText()
    // textFieldState.text :
    // textFieldState.selection : TextRange(0, 0)

למידע על פונקציות אחרות של TextFieldState, אפשר לעיין בחומר העזר בנושא TextFieldState.

שינוי קלט של משתמשים

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

סינון קלט של משתמשים באמצעות טרנספורמציות של קלט

טרנספורמציה של קלט מאפשרת לסנן קלט מהמשתמש. לדוגמה, אם TextField מקבל מספר טלפון אמריקאי, אתם רוצים לאפשר רק 10 ספרות. התוצאות של InputTransformation נשמרות בTextFieldState.

יש מסננים מובנים לתרחישי שימוש נפוצים ב-InputTransformation. כדי להגביל את האורך, צריך להתקשר למספר InputTransformation.maxLength():

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine,
    inputTransformation = InputTransformation.maxLength(10)
)

שינויים בהזנה בהתאמה אישית

‫InputTransformation הוא ממשק פונקציה יחידה. כשמטמיעים את InputTransformation המותאם אישית, צריך לבטל את ההגדרה של TextFieldBuffer.transformInput:

class CustomInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
    }
}

כדי להוסיף מספר טלפון, מוסיפים טרנספורמציה מותאמת אישית של קלט שמאפשרת להקליד רק ספרות ב-TextField:

class DigitOnlyInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
        if (!asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    }
}

טרנספורמציות של קלט בשרשרת

כדי להוסיף כמה מסננים לקלט הטקסט, משרשרים InputTransformations באמצעות פונקציית התוסף then. המסננים מופעלים ברצף. מומלץ להחיל קודם את המסננים הסלקטיביים ביותר כדי למנוע טרנספורמציות מיותרות על נתונים שבסופו של דבר יסוננו.

TextField(
    state = rememberTextFieldState(),
    inputTransformation = InputTransformation.maxLength(6)
        .then(CustomInputTransformation()),
)

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

עיצוב הקלט לפני שהוא מוצג

OutputTransformationמאפשרים לכם לעצב את קלט המשתמש לפני שהוא מוצג במסך. בניגוד ל-InputTransformation, העיצוב שנעשה באמצעות התג OutputTransformation לא נשמר ב-TextFieldState. בהמשך לדוגמה הקודמת של מספר הטלפון, צריך להוסיף סוגריים ומקפים במקומות המתאימים:

מספר טלפון אמריקאי, בפורמט הנכון עם סוגריים, מקפים ומספרים מתאימים.
איור 3. מספר טלפון אמריקאי בפורמט הנכון עם האינדקסים המתאימים.

זו הדרך המעודכנת לטפל בVisualTransformations בTextFields מבוססי-ערך. ההבדל העיקרי הוא שלא צריך לחשב את מיפויי ההיסט שלהם.

‫OutputTransformation הוא ממשק של שיטה מופשטת יחידה. כדי להטמיע OutputTransformationבהתאמה אישית, צריך לבטל את השיטה transformOutput:

class CustomOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
    }
}

כדי להוסיף פורמט למספר טלפון, מוסיפים סוגר פותח באינדקס 0, סוגר סוגר באינדקס 4 ומקף באינדקס 8 ל-OutputTransformation:

class PhoneNumberOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
}

בשלב הבא, מוסיפים את OutputTransformation אל TextField:

TextField(
    state = rememberTextFieldState(),
    outputTransformation = PhoneNumberOutputTransformation()
)

איך טרנספורמציות פועלות יחד

הדיאגרמה הבאה מציגה את התהליך מקלט טקסט ועד לטרנספורמציה לפלט:

תצוגה חזותית של תהליך השינוי שעובר קלט טקסט עד שהוא הופך לפלט טקסט.
איור 4. דיאגרמה שמראה איך קלט טקסט עובר טרנספורמציות לפני שהוא הופך לפלט טקסט.
  1. הקלט מתקבל ממקור הקלט.
  2. הקלט מסונן באמצעות InputTransformation, שנשמר ב-TextFieldState.
  3. הקלט מועבר דרך OutputTransformation כדי לעצב אותו.
  4. הקלט מוצג בTextField.

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

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

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

מקורות מידע נוספים