پیکربندی فیلدهای نوشتاری

TextField به کاربران اجازه می‌دهد نوشتار وارد کنند و آن را تغییر دهند. دو نوع فیلد نوشتاری وجود دارد که می‌توانید استفاده کنید: فیلدهای نوشتاری مبتنی بر وضعیت و فیلدهای نوشتاری مبتنی بر مقدار. نوعی را که می‌خواهید محتوای آن نمایش داده شود انتخاب کنید:

توصیه می‌کنیم از فیلدهای نوشتاری مبتنی بر وضعیت استفاده کنید، زیرا این فیلدها رویکردی کامل‌تر و قابل‌اعتمادتر برای مدیریت وضعیت TextField ارائه می‌دهند. جدول زیر تفاوت‌های بین این انواع فیلدهای نوشتاری را نشان می‌دهد و مزایای کلیدی فیلدهای نوشتاری مبتنی بر وضعیت را ارائه می‌دهد:

ویژگی

فیلدهای نوشتاری مبتنی بر مقدار

فیلدهای نوشتاری مبتنی بر وضعیت

مزایای مبتنی بر ایالت

مدیریت وضعیت

وضعیت فیلد نوشتاری را با onValueChange پس‌تماس به‌روز می‌کند. شما مسئول به‌روزرسانی value در ایالت خودتان براساس تغییراتی هستید که onValueChange گزارش کرده است.

به‌طور صریح از یک شیء TextFieldState برای مدیریت وضعیت ورودی نوشتار (مقدار، انتخاب، و ترکیب) استفاده می‌کند. این وضعیت می‌تواند به‌خاطر سپرده و هم‌رسانی شود.

  • ‫onValueChange پاسخ‌به‌تماس برداشته شده است، که مانع از معرفی رفتارهای ناهم‌زمان می‌شود.
  • وضعیت درطول بازسازی، پیکربندی، و مرگ فرایند حفظ می‌شود.

تبدیل دیداری

از VisualTransformation برای اصلاح نحوه نمایش نوشتار استفاده می‌کند. این معمولاً قالب‌بندی ورودی و خروجی را در یک مرحله انجام می‌دهد.

از InputTransformation برای اصلاح ورودی کاربر قبل‌از اینکه به وضعیت متعهد شود و از OutputTransformation برای قالب‌بندی محتوای فیلد نوشتاری بدون تغییر دادن داده‌های وضعیت زیربنایی استفاده می‌کند.

  • دیگر لازم نیست نگاشت افست بین نوشتار خام اصلی و نوشتار تبدیل‌شده را با OutputTransformation ارائه دهید.

محدودیت‌های خط

‫singleLine: Boolean, maxLines: Int و minLines: Int را برای کنترل تعداد خطوط می‌پذیرد.

از lineLimits: TextFieldLineLimits برای پیکربندی حداقل و حداکثر تعداد خطوطی که فیلد نوشتاری می‌تواند اشغال کند استفاده می‌کند.

  • با ارائه پارامتر lineLimits از نوع TextFieldLineLimits، ابهام را هنگام پیکربندی محدودیت‌های خط برطرف می‌کند.

فیلد نوشتاری امن

موجود نیست

‫SecureTextField یک عنصر ترکیبی است که در بالای فیلدهای نوشتاری مبتنی بر وضعیت برای نوشتن فیلد گذرواژه ساخته شده است.

  • به شما امکان می‌دهد امنیت را در زیرینه بهینه‌سازی کنید و با میانای کاربر ازپیش تعریف‌شده‌ای با textObfuscationMode ارائه می‌شود.

این صفحه توضیح می‌دهد که چگونه می‌توانید TextField را پیاده‌سازی کنید، ورودی TextField را سبک‌بندی کنید، و گزینه‌های دیگر TextField را، مثل گزینه‌های صفحه‌کلید و تبدیل دیداری ورودی کاربر، پیکربندی کنید.

انتخاب پیاده‌سازی TextField

دو سطح پیاده‌سازی TextField وجود دارد:

  1. ‫TextField پیاده‌سازی «طراحی مواد» است. توصیه می‌کنیم این پیاده‌سازی را انتخاب کنید زیرا از دستورالعمل‌های طراحی مواد پیروی می‌کند:
    • سبک‌پردازی پیش‌فرض پرشده است
    • ‫OutlinedTextField نسخه سبک‌دار خطوط محیطی است
  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 Material» یا «OutlinedTextField» نیاز دارد، TextField را به‌جای BasicTextField توصیه می‌کنیم. بااین‌حال، هنگام ساختن طرح‌هایی که به تزئینات مشخصات Material نیاز ندارند، باید از BasicTextField استفاده شود.

سبک ورودی با 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 با نوشتار «نام کاربری» که در داخل فیلد نوشتاری ظاهر می‌شود.
شکل ۲. ‫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()
)

نحوه عملکرد تبدیل‌ها با یکدیگر

نمودار زیر جریان از ورودی نوشتاری به تبدیل به برونداد را نشان می‌دهد:

تصویرسازی از نحوه تبدیل ورودی نوشتار قبل‌از تبدیل شدن به برونداد نوشتار.
شکل ۴. نموداری که نشان می‌دهد ورودی نوشتار قبل‌از تبدیل شدن به برونداد نوشتار چگونه از میان تبدیل‌ها عبور می‌کند.
  1. ورودی از منبع ورودی دریافت می‌شود.
  2. ورودی ازطریق InputTransformation فیلتر می‌شود که در TextFieldState ذخیره می‌شود.
  3. ورودی برای قالب‌بندی ازطریق OutputTransformation ارسال می‌شود.
  4. ورودی در TextField ارائه می‌شود.

تنظیم گزینه‌های صفحه‌کلید

‫TextField به شما امکان می‌دهد گزینه‌های پیکربندی صفحه‌کلید، مانند چیدمان صفحه‌کلید، را تنظیم کنید یا اگر صفحه‌کلید از تصحیح خودکار پشتیبانی می‌کند، آن را فعال کنید. اگر صفحه‌کلید نرم‌افزاری از گزینه‌های ارائه‌شده در اینجا پیروی نکند، ممکن است برخی‌از گزینه‌ها تضمین نشوند. در اینجا فهرست گزینه‌های صفحه‌کلید پشتیبانی‌شده آمده است:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

منابع بیشتر