يسمح TextField للمستخدمين بإدخال النص وتعديله. هناك نوعان من حقول النص التي يمكنك استخدامها: حقول النص المستندة إلى الحالة وحقول النص المستندة إلى القيمة. اختَر النوع الذي تريد عرض المحتوى له:
ننصح باستخدام حقول نصية مستندة إلى الحالة، لأنّها توفّر طريقة أكثر اكتمالاً وموثوقية لإدارة حالة TextField. يوضح الجدول التالي
الاختلافات بين هذه الأنواع من الحقول النصية، ويتضمن المزايا
الرئيسية التي توفرها الحقول النصية المستندة إلى الحالة:
الميزة |
الحقول النصية المستندة إلى القيمة |
الحقول النصية المستندة إلى الحالة |
مزايا خاصة بالولاية |
|---|---|---|---|
إدارة الحالة |
يتم تعديل حالة حقل النص باستخدام دالة الاستدعاء |
يستخدم بشكل صريح عنصر |
|
التحوّل المرئي |
يستخدم |
يستخدم |
|
الحدود القصوى لعدد الأسطر |
يقبل |
يستخدم |
|
حقل نصي آمن |
لا ينطبق |
|
|
توضّح هذه الصفحة كيفية
تنفيذ TextField وتنسيق إدخال TextField وضبط
خيارات TextField الأخرى، مثل خيارات لوحة المفاتيح وتحويل
إدخال المستخدم بشكل مرئي.
اختيار طريقة تنفيذ TextField
هناك مستويان لتنفيذ TextField:
-
TextFieldهو تنفيذ التصميم المتعدد الأبعاد. ننصحك باختيار هذه الطريقة لأنّها تتّبع إرشادات التصميم المتعدد الأبعاد: - يتيح
BasicTextFieldللمستخدمين تعديل النص باستخدام لوحة المفاتيح المادية أو لوحة المفاتيح الافتراضية، ولكنّه لا يوفّر أيّ عناصر تزيينية، مثل التلميحات أو العناصر النائبة.
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
OutlinedTextField( state = rememberTextFieldState(), label = { Text("Label") } )
النمط TextField
يتشارك TextField وBasicTextField العديد من المَعلمات الشائعة للتخصيص.
تتوفّر القائمة الكاملة لـ TextField في
رمز مصدر TextField. في ما يلي قائمة غير شاملة ببعض المَعلمات المفيدة:
textStylelineLimits
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.
ضبط حدود الخطوط
تتيح الدوال المركّبة TextField التمرير على طول محور واحد. يتم تحديد سلوك الانتقال من خلال المَعلمة lineLimits. يتم ضبط TextFields للانتقال أفقيًا في سطر واحد، بينما يتم الانتقال عموديًا في TextFields متعددة الأسطر.
استخدِم TextFieldLineLimits لاختيار إعدادات السطر المناسبة لـ TextField:
TextField( state = rememberTextFieldState(), lineLimits = TextFieldLineLimits.SingleLine )
يتميّز إعداد SingleLine بالسمات التالية:
- لا يتم التفاف النص مطلقًا، ولا يسمح بأسطر جديدة.
- يتميز عنصر "
TextField" دائمًا بارتفاع ثابت. - إذا تجاوز النص المساحة المخصّصة له، يتم الانتقال إليه أفقيًا.
TextField( state = rememberTextFieldState("Hello\nWorld\nHello\nWorld"), lineLimits = TextFieldLineLimits.MultiLine(1, 4) )
يتميّز إعداد MultiLine بالسمات التالية:
- تقبل هذه الدالة مَعلمتَين:
minHeightInLinesوmaxHeightInLines. - يبلغ طول حقل النص
minHeightInLinesعلى الأقل. - إذا تجاوز النص الحد الأقصى، سيتم التفافه.
- إذا كان النص يتطلّب المزيد من الأسطر، يتوسّع الحقل حتى يصل ارتفاعه إلى
maxHeightInLines، ويتم التمرير عموديًا.
تنسيق الإدخال باستخدام 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) )
TextFieldإدارة حالة حقل النص
يستخدم TextField عنصر الاحتفاظ بالحالة المخصّص الذي يُسمى TextFieldState للمحتوى والاختيار. تم تصميم TextFieldState ليتم رفعه
أينما كان مناسبًا في البنية. هناك سمتان رئيسيتان يوفّرهما TextFieldState:
-
initialText: محتوىTextField. -
initialSelection: يشير إلى مكان المؤشر أو النص المحدّد.
ما يميّز TextFieldState عن الطرق الأخرى، مثل دالة الاستدعاء 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 مع "اسم المستخدم" كنص أوّلي.تعديل النص باستخدام 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 أرقام كحد أقصى.
تنسيق الإدخال قبل عرضه
تتيح لك OutputTransformations تنسيق إدخال المستخدم قبل عرضه على الشاشة. على عكس InputTransformation، لا يتم حفظ التنسيق الذي يتم إجراؤه من خلال OutputTransformation في TextFieldState. بناءً على مثال رقم الهاتف السابق، تحتاج إلى إضافة أقواس وشرطات في الأماكن المناسبة:
هذه هي الطريقة المعدَّلة للتعامل مع VisualTransformation في TextField المستندة إلى القيمة، مع اختلاف رئيسي يتمثل في أنّه ليس عليك احتساب عمليات ربط الإزاحة.
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() )
كيفية عمل عمليات التحويل معًا
يوضح المخطط التالي التدفق من إدخال النص إلى التحويل إلى الإخراج:
- يتم تلقّي الإدخال من مصدر الإدخال.
- تتم فلترة الإدخال من خلال
InputTransformation، ويتم حفظه في TextFieldState. - يتم تمرير الإدخال من خلال
OutputTransformationللتنسيق. - يتم عرض الإدخال في
TextField.
ضبط خيارات لوحة المفاتيح
يتيح لك TextField ضبط خيارات إعدادات لوحة المفاتيح، مثل تنسيق لوحة المفاتيح، أو تفعيل ميزة التصحيح التلقائي إذا كانت لوحة المفاتيح تتيح ذلك. قد لا تكون بعض الخيارات مضمونة إذا كانت لوحة المفاتيح الافتراضية لا تتوافق مع الخيارات المقدَّمة هنا. في ما يلي قائمة بخيارات لوحة المفاتيح المتوافقة:
capitalizationautoCorrectkeyboardTypeimeAction
تتضمّن فئة KeyboardOptions الآن مَعلمة منطقية جديدة،
وهي showKeyboardOnFocus، والتي تستخدمها خصيصًا لمكوّنات TextField
المدمجة مع TextFieldState. يتحكّم هذا الخيار في سلوك لوحة المفاتيح الافتراضية عندما يتم التركيز على TextField من خلال وسائل أخرى غير تفاعل المستخدم المباشر (على سبيل المثال، آليًا).
عند ضبط السمة KeyboardOptions.showKeyboardOnFocus على "صحيح"، لا تظهر لوحة المفاتيح الافتراضية تلقائيًا إذا تم التركيز على TextField بشكل غير مباشر. في هذه الحالات، يجب أن ينقر المستخدم صراحةً على TextField نفسه لإظهار لوحة المفاتيح.
تحديد منطق التفاعل مع لوحة المفاتيح
يتيح زر الإجراء في لوحة المفاتيح الافتراضية على Android تقديم ردود تفاعلية داخل تطبيقك. لمزيد من المعلومات حول ضبط زر الإجراء، يُرجى الاطّلاع على قسم ضبط خيارات لوحة المفاتيح.
لتحديد ما يحدث عندما ينقر المستخدم على زر الإجراء هذا، استخدِم المَعلمة onKeyboardAction. تقبل هذه المَعلمة واجهة وظيفية اختيارية باسم KeyboardActionHandler. تحتوي واجهة KeyboardActionHandler على طريقة واحدة، وهي onKeyboardAction(performDefaultAction: () -> Unit).
من خلال توفير طريقة تنفيذ لهذه الطريقة onKeyboardAction، يمكنك
إدخال منطق مخصّص يتم تنفيذه عندما يضغط المستخدم على زر الإجراء في لوحة المفاتيح.
تتوفّر عدة أنواع عادية من إجراءات لوحة المفاتيح مع إعدادات تلقائية مضمّنة.
على سبيل المثال، سيؤدي اختيار ImeAction.Next أو ImeAction.Previous كنوع الإجراء إلى نقل التركيز تلقائيًا إلى حقل الإدخال التالي أو السابق على التوالي. وبالمثل، يؤدي زر الإجراء الذي تم ضبطه على ImeAction.Done عادةً إلى إغلاق لوحة المفاتيح الافتراضية. يتم تنفيذ هذه الوظائف التلقائية
تلقائيًا ولا تتطلّب منك تقديم KeyboardActionHandler.
يمكنك أيضًا تنفيذ سلوك مخصّص بالإضافة إلى هذه الإجراءات التلقائية.
عند تقديم KeyboardActionHandler، تتلقّى طريقة onKeyboardAction
دالة performDefaultAction. يمكنك استدعاء دالة performDefaultAction() هذه في أي وقت ضمن المنطق المخصّص لتفعيل الإعداد التلقائي المرتبط بإجراء "محرر أسلوب الإدخال" الحالي أيضًا.
TextField( state = textFieldViewModel.usernameState, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next), onKeyboardAction = { performDefaultAction -> textFieldViewModel.validateUsername() performDefaultAction() } )
يوضّح هذا المقتطف حالة استخدام شائعة على شاشة تسجيل
تتضمّن حقل اسم المستخدم. بالنسبة إلى هذا الحقل، تم اختيار ImeAction.Next
لزر إجراء لوحة المفاتيح. يتيح هذا الخيار التنقل السريع والسلس إلى
حقل كلمة المرور اللاحق.
بالإضافة إلى هذا التنقّل العادي، هناك شرط لبدء عملية التحقّق من اسم المستخدم في الخلفية أثناء انتقال المستخدم لإدخال كلمة المرور. للتأكّد من الاحتفاظ بسلوك تبديل التركيز التلقائي المتأصل في ImeAction.Next إلى جانب عملية تحقّق مخصّصة، يتم استدعاء الدالة performDefaultAction(). يؤدي استدعاء performDefaultAction() إلى تشغيل نظام إدارة التركيز الأساسي ضمنيًا لنقل التركيز إلى عنصر في واجهة المستخدم المناسب التالي، مع الحفاظ على مسار التنقل المتوقع.
إنشاء حقل كلمة مرور آمنة
SecureTextField هي دالة مركّبة تستند إلى حقول نصية مستندة إلى الحالة
لكتابة حقل كلمة مرور. ننصح باستخدام SecureTextField لإنشاء حقول نصية لكلمات المرور، لأنّه يخفي الأحرف التي يتم إدخالها تلقائيًا ويوقف إجراءات القص والنسخ.
يحتوي SecureTextField على textObfuscationMode، والذي يتحكم في كيفية رؤية المستخدم
لإدخال الأحرف. تتوفّر لـ "textObfuscationMode" الخيارات التالية:
Hidden: لإخفاء جميع المدخلات الإعداد التلقائي على أجهزة الكمبيوتر المكتبي
Visible: يعرض جميع المدخلات.
RevealLastTyped: لإخفاء كل الإدخالات باستثناء الحرف الأخير الإعداد التلقائي على الأجهزة الجوّالة
مراجع إضافية
- التنسيق التلقائي لرقم هاتف في حقل نصي
- إظهار كلمة المرور أو إخفاؤها استنادًا إلى زر تبديل يفعّله المستخدم
- التحقّق من صحة الإدخال أثناء كتابة المستخدم