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) )
وقتی طراحی شما به Material TextField یا OutlinedTextField نیاز دارد، TextField را بهجای BasicTextField توصیه میکنیم. بااینحال، هنگام ساختن طرحهایی که به تزئینات مشخصات Material نیاز ندارند، باید از BasicTextField استفاده شود.
پیکربندی محدودیتهای خط
TextField ترکیبپذیرها از پیمایش در امتداد یک محور پشتیبانی میکنند. رفتار پیمایش
با پارامتر lineLimits تعیین میشود. TextFieldهای پیکربندیشده
برای یک خط بهصورت افقی پیمایش میکنند، درحالیکه TextFieldهای چندخطی بهصورت
عمودی پیمایش میکنند.
از 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 شما شماره تلفن آمریکایی دریافت میکند، فقط میخواهید ۱۰
رقم را بپذیرید. نتایج 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() } } }
تبدیلهای ورودی زنجیرهای
برای افزودن چند فیلتر به ورودی نوشتاری، InputTransformationها را بااستفاده از
تابع افزونه then زنجیر کنید. فیلترها بهصورت متوالی اجرا میشوند. بهعنوان
یک روال مطلوب، ابتدا گزینشیترین فیلترها را اعمال کنید تا از تبدیلهای غیرضروری
روی دادههایی که درنهایت فیلتر میشوند جلوگیری شود.
TextField( state = rememberTextFieldState(), inputTransformation = InputTransformation.maxLength(6) .then(CustomInputTransformation()), )
پساز افزودن تبدیلهای ورودی، ورودی TextField حداکثر ۱۰ رقم را میپذیرد.
قالببندی ورودی قبلاز نمایش آن
OutputTransformations به شما امکان میدهد ورودی کاربر را قبلاز نمایش در صفحه قالببندی کنید. برخلاف InputTransformation، قالببندی انجامشده ازطریق
OutputTransformation در TextFieldState ذخیره نمیشود. بااستفاده از مثال شماره تلفن قبلی، باید پرانتز و خط تیره را در جاهای مناسب اضافه کنید:
این روش بهروزشدهای برای مدیریت VisualTransformation در TextField مبتنی بر مقدار است، با این تفاوت کلیدی که نیازی به محاسبه نگاشتهای جابهجایی آنها ندارید.
OutputTransformation یک میانای روش انتزاعی واحد است. برای
پیادهسازی OutputTransformation سفارشی، باید روش
transformOutput را لغو کنید:
class CustomOutputTransformation : OutputTransformation { override fun TextFieldBuffer.transformOutput() { } }
برای قالببندی شماره تلفن، پرانتز باز را در نمایه ۰، پرانتز بسته را در نمایه ۴، و خط تیره را در نمایه ۸ به 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 روی true تنظیم شده باشد، اگر TextField بهطور غیرمستقیم فوکوس را دریافت کند،
صفحهکلید نرمافزاری بهطور خودکار ظاهر نمیشود. در
چنین مواردی، کاربر باید صریحاً روی خود TextField تکضرب بزند تا
صفحهکلید نمایان شود.
تعریف منطق تعامل صفحهکلید
دکمه کنش در صفحهکلید نرمافزاری Android امکان پاسخهای تعاملی را در برنامهتان فراهم میکند. برای اطلاعات بیشتر درباره پیکربندی دکمه کنش، به بخش تنظیم گزینههای صفحهکلید مراجعه کنید.
برای تعریف کردن اینکه وقتی کاربر روی این دکمه کنش ضربه میزند چه اتفاقی میافتد، از پارامتر
onKeyboardAction استفاده کنید. این پارامتر یک میانای کاربردی اختیاری
بهنام KeyboardActionHandler را میپذیرد. میانای KeyboardActionHandler
شامل یک روش، onKeyboardAction(performDefaultAction: () -> Unit)، است.
با ارائه پیادهسازی برای این روش onKeyboardAction، میتوانید
منطق سفارشی را معرفی کنید که وقتی کاربر دکمه کنش صفحهکلید را فشار میدهد
اجرا میشود.
چندین نوع کنش استاندارد صفحهکلید با رفتارهای پیشفرض داخلی ارائه میشوند.
برای مثال، انتخاب ImeAction.Next یا ImeAction.Previous بهعنوان نوع کنش، بهطور پیشفرض، تمرکز را بهترتیب به فیلد ورودی بعدی یا قبلی منتقل میکند. بهطور مشابه، دکمه کنشی که روی ImeAction.Done تنظیم شده است معمولاً
صفحهکلید نرمافزاری را میبندد. این عملکردهای پیشفرض بهطور خودکار اجرا میشوند و نیازی نیست KeyboardActionHandler ارائه دهید.
علاوهبر این کنشهای پیشفرض، میتوانید رفتار سفارشی نیز پیادهسازی کنید.
وقتی KeyboardActionHandler را ارائه میدهید، روش onKeyboardAction آن
تابع performDefaultAction را دریافت میکند. میتوانید این تابع performDefaultAction() را در هر نقطهای از منطق سفارشی خود فراخوانی کنید تا رفتار پیشفرض استاندارد مرتبط با کنش IME فعلی را نیز راهاندازی کنید.
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: همه ورودیها بهجز آخرین نویسه را پنهان میکند. رفتار پیشفرض در دستگاههای همراه.
منابع بیشتر
- قالببندی خودکار شماره تلفن در فیلد نوشتار
- نمایش یا پنهان کردن گذرواژه براساس کلید روشن/خاموش کاربر
- اعتبارسنجی ورودی همزمان با تایپ کردن کاربر