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

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)
)

कई लाइन वाला टेक्स्ट फ़ील्ड, जिसमें बदलाव की जा सकने वाली दो लाइनें और लेबल शामिल हैं

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

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

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

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

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

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

सिर्फ़ टेक्स्ट के एक हिस्से को पसंद के मुताबिक बनाने के लिए, buildAnnotatedString और SpanStyle के साथ-साथ linearGradient का इस्तेमाल करना.
पहली इमेज. 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,
)

टेक्स्ट फ़ील्ड के अंदर Username टेक्स्ट वाला एक TextField.
दूसरी इमेज. TextField, जिसमें शुरुआती टेक्स्ट के तौर पर "Username" मौजूद है.

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()

LaunchedEffect(phoneNumberState) {
    phoneNumberState.edit { // TextFieldBuffer scope
        append("123456789")
    }
}

TextField(
    state = phoneNumberState,
    inputTransformation = InputTransformation { // TextFieldBuffer scope
        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 जैसे तरीकों का इस्तेमाल किया जा सके.

    val usernameState = rememberTextFieldState("I love Android")
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    usernameState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    usernameState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • setTextAndPlaceCursorAtEnd: इससे मौजूदा टेक्स्ट मिट जाता है और उसकी जगह दिया गया टेक्स्ट आ जाता है. साथ ही, कर्सर को आखिर में सेट कर दिया जाता है.

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

  • clearText: इससे पूरा टेक्स्ट मिट जाता है.

    usernameState.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 को लागू करते समय, आपको InputTransformation को बदलना होगा:TextFieldBuffer.transformInput

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

किसी फ़ोन नंबर के लिए, इनपुट में बदलाव करने की सुविधा जोड़ें. इससे सिर्फ़ अंकों को TextField में टाइप किया जा सकेगा:

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

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

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

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

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

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

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

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

यह वैल्यू के आधार पर तय होने वाले 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

अन्य संसाधन