टेक्स्ट फ़ील्ड कॉन्फ़िगर करना

TextField की मदद से, उपयोगकर्ता टेक्स्ट डाल सकते हैं और उसमें बदलाव कर सकते हैं. दो तरह के टेक्स्ट फ़ील्ड इस्तेमाल किए जा सकते हैं: स्टेट-बेस्ड टेक्स्ट फ़ील्ड और वैल्यू-बेस्ड टेक्स्ट फ़ील्ड. वह टाइप चुनें जिसके लिए आपको कॉन्टेंट दिखाना है:

हमारा सुझाव है कि आप स्टेट-बेस्ड टेक्स्ट फ़ील्ड का इस्तेमाल करें. इनसे TextField की स्थिति को मैनेज करने का ज़्यादा बेहतर और भरोसेमंद तरीका मिलता है. यहां दी गई टेबल में, इन दोनों तरह के टेक्स्ट फ़ील्ड के बीच के अंतर को बताया गया है. साथ ही, इसमें स्टेट-बेस्ड टेक्स्ट फ़ील्ड के मुख्य फ़ायदों के बारे में बताया गया है:

सुविधा

वैल्यू के आधार पर टेक्स्ट फ़ील्ड

राज्य के हिसाब से टेक्स्ट फ़ील्ड

राज्य के हिसाब से मिलने वाले फ़ायदे

स्टेट मैनेजमेंट

onValueChange कॉलबैक की मदद से, टेक्स्ट फ़ील्ड की स्थिति को अपडेट करता है. onValueChange की ओर से बताए गए बदलावों के आधार पर, अपने राज्य में value को अपडेट करने की ज़िम्मेदारी आपकी है.

टेक्स्ट इनपुट की स्थिति (वैल्यू, चुने गए विकल्प, और कंपोज़िशन) को मैनेज करने के लिए, साफ़ तौर पर TextFieldState ऑब्जेक्ट का इस्तेमाल करता है. इस स्थिति को याद रखा जा सकता है और शेयर किया जा सकता है.

  • onValueChange कॉलबैक को हटा दिया गया है. इससे आपको एसिंक्रोनस व्यवहार को लागू करने से रोका जा सकता है.
  • यह स्थिति, फिर से कंपोज़ करने, कॉन्फ़िगरेशन, और प्रोसेस बंद होने के बाद भी बनी रहती है.

विज़ुअल ट्रांसफ़ॉर्मेशन

दिखाए गए टेक्स्ट के दिखने के तरीके में बदलाव करने के लिए, VisualTransformation का इस्तेमाल करता है. आम तौर पर, यह एक ही चरण में इनपुट और आउटपुट, दोनों को फ़ॉर्मैट करता है.

यह उपयोगकर्ता के इनपुट को स्टेट में सेव करने से पहले, उसमें बदलाव करने के लिए InputTransformation का इस्तेमाल करता है. साथ ही, स्टेट के डेटा में बदलाव किए बिना, टेक्स्ट फ़ील्ड के कॉन्टेंट को फ़ॉर्मैट करने के लिए OutputTransformation का इस्तेमाल करता है.

  • अब आपको OutputTransformation का इस्तेमाल करके, ओरिजनल रॉ टेक्स्ट और बदले गए टेक्स्ट के बीच ऑफ़सेट मैपिंग देने की ज़रूरत नहीं है.

लाइन की सीमाएं

लाइनों की संख्या को कंट्रोल करने के लिए, singleLine: Boolean, maxLines: Int और minLines: Int को स्वीकार करता है.

टेक्स्ट फ़ील्ड में कम से कम और ज़्यादा से ज़्यादा कितनी लाइनें हो सकती हैं, यह कॉन्फ़िगर करने के लिए lineLimits: TextFieldLineLimits का इस्तेमाल करता है.

  • TextFieldLineLimits टाइप का lineLimits पैरामीटर देकर, लाइन की सीमाएं कॉन्फ़िगर करते समय होने वाली गड़बड़ी को दूर करता है.

सुरक्षित टेक्स्ट फ़ील्ड

लागू नहीं

SecureTextField, पासवर्ड फ़ील्ड लिखने के लिए, स्टेट-आधारित टेक्स्ट फ़ील्ड के ऊपर बनाया गया एक कंपोज़ेबल है.

  • इसकी मदद से, बैकग्राउंड में सुरक्षा को ऑप्टिमाइज़ किया जा सकता है. साथ ही, इसमें textObfuscationMode के साथ पहले से तय किया गया यूज़र इंटरफ़ेस (यूआई) मिलता है.

इस पेज पर बताया गया है कि TextField को कैसे लागू किया जा सकता है, TextField इनपुट को कैसे स्टाइल किया जा सकता है, और TextField के अन्य विकल्पों को कैसे कॉन्फ़िगर किया जा सकता है. जैसे, कीबोर्ड के विकल्प और उपयोगकर्ता के इनपुट को विज़ुअल तौर पर बदलना.

TextField को लागू करने का तरीका चुनें

TextField को लागू करने के दो लेवल हैं:

  1. TextField, मटीरियल डिज़ाइन को लागू करने का तरीका है. हमारा सुझाव है कि आप इस तरीके को चुनें, क्योंकि यह मटीरियल डिज़ाइन के दिशा-निर्देशों का पालन करता है:
  2. BasicTextField की मदद से, उपयोगकर्ता हार्डवेयर या सॉफ़्टवेयर कीबोर्ड का इस्तेमाल करके टेक्स्ट में बदलाव कर सकते हैं. हालांकि, इसमें हिंट या प्लेसहोल्डर जैसी कोई सजावट नहीं होती.

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, जिसमें बदलाव की जा सकने वाली दो लाइनें और लेबल शामिल है

जब आपके डिज़ाइन में मटीरियल TextField या OutlinedTextField की ज़रूरत हो, तब हमारा सुझाव है कि आप BasicTextField के बजाय TextField का इस्तेमाल करें. हालांकि, BasicTextField का इस्तेमाल ऐसे डिज़ाइन बनाते समय किया जाना चाहिए जिनमें Material की खास जानकारी में दी गई सजावट की ज़रूरत नहीं होती.

Brush API की मदद से इनपुट को स्टाइल करना

TextField में ज़्यादा बेहतर स्टाइलिंग के लिए, Brush API का इस्तेमाल किया जा सकता है. यहां दिए गए सेक्शन में, TextField इनपुट में कलर ग्रेडिएंट जोड़ने के लिए, ब्रश का इस्तेमाल करने का तरीका बताया गया है.

टेक्स्ट को स्टाइल करने के लिए, Brush API का इस्तेमाल करने के बारे में ज़्यादा जानने के लिए, Brush API की मदद से बेहतर स्टाइलिंग की सुविधा चालू करना लेख पढ़ें.

TextStyle का इस्तेमाल करके, कलर ग्रेडिएंट लागू करना

TextField में टाइप करते समय कलर ग्रेडिएंट लागू करने के लिए, अपनी पसंद के ब्रश को TextField के लिए TextStyle के तौर पर सेट करें. इस उदाहरण में, हम 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)
)

टेक्स्ट फ़ील्ड में टेक्स्ट टाइप किया जा रहा है. इसमें इंद्रधनुष के ग्रेडिएंट वाला इफ़ेक्ट दिख रहा है.
पहली इमेज. TextField कॉन्टेंट के लिए, इंद्रधनुष के रंगों वाला ग्रेडिएंट इफ़ेक्ट.

टेक्स्ट फ़ील्ड की स्थिति मैनेज करना

TextField अपने कॉन्टेंट और चुने गए आइटम के लिए, TextFieldState नाम की खास स्टेट होल्डर क्लास का इस्तेमाल करता है. TextFieldState को इस तरह से डिज़ाइन किया गया है कि इसे आपके आर्किटेक्चर में कहीं भी होस्ट किया जा सकता है. TextFieldState दो मुख्य प्रॉपर्टी उपलब्ध कराता है:

  • initialText: TextField का कॉन्टेंट.
  • initialSelection: इससे पता चलता है कि कर्सर या चुना गया टेक्स्ट कहां है.

TextFieldState को onValueChange कॉलबैक जैसे अन्य तरीकों से अलग बनाने वाली बात यह है कि TextFieldState, इनपुट फ़्लो को पूरी तरह से एनकैप्सुलेट करता है. इसमें सही बैकिंग डेटा स्ट्रक्चर का इस्तेमाल करना, फ़िल्टर और फ़ॉर्मैटर को इनलाइन करना, और अलग-अलग सोर्स से किए गए सभी बदलावों को सिंक करना शामिल है.

TextField में स्टेट को होस्ट करने के लिए, TextFieldState() का इस्तेमाल किया जा सकता है. इसके लिए, हमारा सुझाव है कि आप 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, जिसमें टेक्स्ट फ़ील्ड के अंदर 'उपयोगकर्ता नाम' टेक्स्ट दिख रहा है.
दूसरी इमेज. 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()
        }
    }
}

चेन इनपुट ट्रांसफ़ॉर्मेशन

अपने टेक्स्ट इनपुट में कई फ़िल्टर जोड़ने के लिए, then एक्सटेंशन फ़ंक्शन का इस्तेमाल करके InputTransformation को चेन करें. फ़िल्टर एक के बाद एक लागू होते हैं. सबसे सही तरीका यह है कि सबसे पहले उन फ़िल्टर को लागू करें जो सबसे ज़्यादा चुनिंदा हैं. इससे, डेटा में ऐसे ग़ैर-ज़रूरी बदलावों से बचा जा सकता है जिन्हें आखिर में फ़िल्टर कर दिया जाएगा.

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

इनपुट ट्रांसफ़ॉर्मेशन जोड़ने के बाद, TextField इनपुट में ज़्यादा से ज़्यादा 10 अंक डाले जा सकते हैं.

इनपुट को दिखाने से पहले उसे फ़ॉर्मैट करना

OutputTransformations की मदद से, उपयोगकर्ता के इनपुट को स्क्रीन पर रेंडर होने से पहले फ़ॉर्मैट किया जा सकता है. InputTransformation के उलट, OutputTransformation की मदद से की गई फ़ॉर्मैटिंग, TextFieldState में सेव नहीं होती. फ़ोन नंबर के पिछले उदाहरण के आधार पर, आपको सही जगहों पर ब्रैकेट और डैश जोड़ने होंगे:

अमेरिका का एक फ़ोन नंबर, जिसे ब्रैकेट, डैश, और सही इंडेक्स के साथ सही तरीके से फ़ॉर्मैट किया गया है.
तीसरी इमेज. अमेरिका का एक फ़ोन नंबर, जो सही फ़ॉर्मैट और इंडेक्स के साथ हो.

वैल्यू पर आधारित TextField में VisualTransformation को मैनेज करने का यह नया तरीका है. इसमें मुख्य अंतर यह है कि आपको उनके ऑफ़सेट मैपिंग का हिसाब लगाने की ज़रूरत नहीं है.

OutputTransformation, एक ऐब्स्ट्रैक्ट मेथड इंटरफ़ेस है. कस्टम OutputTransformation लागू करने के लिए, आपको transformOutput तरीके को बदलना होगा:

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

फ़ोन नंबर को फ़ॉर्मैट करने के लिए, अपने OutputTransformation में इंडेक्स 0 पर ओपनिंग ब्रैकेट, इंडेक्स 4 पर क्लोज़िंग ब्रैकेट, और इंडेक्स 8 पर डैश जोड़ें:

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

इसके बाद, TextField में अपना OutputTransformation जोड़ें:

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

ट्रांसफ़ॉर्मेशन ऐक्शन एक साथ कैसे काम करते हैं

इस डायग्राम में, टेक्स्ट इनपुट से लेकर आउटपुट में बदलने तक का फ़्लो दिखाया गया है:

इस विज़ुअल में दिखाया गया है कि टेक्स्ट इनपुट, टेक्स्ट आउटपुट बनने से पहले किस तरह के बदलावों से गुज़रता है.
चौथी इमेज. एक डायग्राम, जिसमें दिखाया गया है कि टेक्स्ट इनपुट, टेक्स्ट आउटपुट बनने से पहले किस तरह के बदलावों से गुज़रता है.
  1. इनपुट सोर्स से इनपुट मिलता है.
  2. इनपुट को InputTransformation की मदद से फ़िल्टर किया जाता है. इसके बाद, इसे TextFieldState में सेव किया जाता है.
  3. इनपुट को फ़ॉर्मैट करने के लिए, OutputTransformation से पास किया जाता है.
  4. इनपुट को TextField में दिखाया जाता है.

कीबोर्ड के विकल्प सेट करना

TextField की मदद से, कीबोर्ड कॉन्फ़िगरेशन के विकल्प सेट किए जा सकते हैं. जैसे, कीबोर्ड का लेआउट या अपने-आप ठीक होने की सुविधा चालू करना. हालांकि, इसके लिए ज़रूरी है कि कीबोर्ड में यह सुविधा काम करती हो. अगर सॉफ़्टवेयर कीबोर्ड, यहां दिए गए विकल्पों का पालन नहीं करता है, तो कुछ विकल्पों की गारंटी नहीं दी जा सकती. यहां इस्तेमाल किए जा सकने वाले कीबोर्ड के विकल्पों की सूची दी गई है:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

अन्य संसाधन