التعامل مع البيانات التي أدخلها المستخدم

يسمح الرمز TextField للمستخدمين بإدخال النص وتعديله. توضّح هذه الصفحة كيفية تنفيذ TextField، ونمط إدخال TextField، وضبط خيارات TextField الأخرى، مثل خيارات لوحة المفاتيح وتحويل إدخالات المستخدم مرئيًا.

اختيار عملية تنفيذ TextField

هناك مستويان لتنفيذ TextField:

  1. TextField هو تنفيذ Material Design. ننصحك باختيار طريقة التنفيذ هذه لأنّها تتّبع إرشادات التصميم المتعدد الأبعاد:
  2. يتيح رمز BasicTextField للمستخدمين تعديل النص باستخدام لوحة مفاتيح برمجية أو حقيقية، ولكن لا يوفّر أي زخارف مثل التلميح أو العنصر النائب.

@Composable
fun SimpleFilledTextFieldSample() {
    var text by remember { mutableStateOf("Hello") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

حقل نصي قابل للتعديل يحتوي على الكلمة

@Composable
fun SimpleOutlinedTextFieldSample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

حقل نصي قابل للتعديل، مع حدود أرجوانية وتصنيف.

النمط TextField

تشترك TextField وBasicTextField في الكثير من المعلمات الشائعة لتخصيصها. تتوفّر القائمة الكاملة لسمة TextField في TextField رمز المصدر. في ما يلي قائمة غير شاملة لبعض المَعلمات المفيدة:

  • singleLine
  • maxLines
  • textStyle

@Composable
fun StyledTextField() {
    var value by remember { mutableStateOf("Hello\nWorld\nInvisible") }

    TextField(
        value = value,
        onValueChange = { value = it },
        label = { Text("Enter text") },
        maxLines = 2,
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(20.dp)
    )
}

حقل نصي متعدّد الأسطر، مع سطرَين قابلَين للتعديل بالإضافة إلى التصنيف

ننصحك باستخدام TextField بدلاً من BasicTextField عندما يتطلّب تصميمك استخدام مادة TextField أو OutlinedTextField. ومع ذلك، يجب استخدام BasicTextField عند إنشاء تصميمات لا تحتاج إلى الزخارف من مواصفات Material.

إدخال الأنماط باستخدام Brush API

يمكنك استخدام Brush API للحصول على تنسيق أكثر تقدّمًا في TextField. يصف القسم التالي كيفية استخدام فرشاة لإضافة تدرج ملوّن إلى الإدخال TextField.

لمزيد من المعلومات حول استخدام Brush API لتعديل النصوص، يمكنك الاطّلاع على تفعيل النمط المتقدّم باستخدام Brush API.

تنفيذ التدرجات الملونة باستخدام TextStyle

لتطبيق تدرج ملوّن أثناء الكتابة داخل TextField، اضبط الفرشاة التي تختارها على TextStyle في TextField. في هذا المثال، نستخدم فرشاة مضمَّنة مع linearGradient لعرض تأثير تدرج قوس قزح أثناء كتابة النص في TextField.

var text by remember { mutableStateOf("") }
val brush = remember {
    Brush.linearGradient(
        colors = rainbowColors
    )
}
TextField(
    value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush)
)

استخدام buildAnnotatedString وSpanStyle، بالإضافة إلى linearGradient، لتخصيص جزء من النص فقط
الشكل 3. استخدام buildAnnotatedString وSpanStyle مع linearGradient لتخصيص جزء من النص فقط

ضبط خيارات لوحة المفاتيح

يتيح لك TextField ضبط خيارات إعدادات لوحة المفاتيح، مثل تنسيق لوحة المفاتيح، أو تفعيل ميزة "التصحيح التلقائي" إذا كانت متاحة في لوحة المفاتيح. قد لا تكون بعض الخيارات مضمونة إذا لم تتوافق لوحة مفاتيح البرنامج مع الخيارات المقدّمة هنا. في ما يلي قائمة بإعدادات keyboard المتوافقة:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

إدخال التنسيق

تسمح لك TextField بضبط VisualTransformation على قيمة الإدخال، مثل استبدال الأحرف بـ * لكلمات المرور أو إدراج واصلات كل 4 أرقام لرقم بطاقة الائتمان:

@Composable
fun PasswordTextField() {
    var password by rememberSaveable { mutableStateOf("") }

    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Enter password") },
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
    )
}

حقل إدخال نص كلمة المرور، مع إخفاء النص

تتوفّر المزيد من الأمثلة في رمز المصدر VisualTransformationSamples.

إدخال البيانات بوضوح

من المهام الشائعة عند تعديل النص إزالة الأحرف البادئة أو تحويل سلسلة الإدخال في كل مرة تتغيّر فيها.

على سبيل المثال، يجب أن تفترض أنّ لوحة المفاتيح قد تُجري تعديلات عشوائية وكبيرة كل onValueChange. قد يحدث ذلك، على سبيل المثال، إذا استخدم المستخدم التصحيح التلقائي أو استبدل كلمة برمز إيموجي أو ميزات التعديل الذكية الأخرى. وللتعامل مع ذلك بشكلٍ صحيح، اكتب أيّ منطق تحويل بافتراض أنّه النص الحالي الذي تم تمريره إلى onValueChange غير مرتبط بالقيمة السابقة أو التالية التي سيتم تمريرها إلى onValueChange.

لتنفيذ حقل نصي لا يسمح بالأصفار البادئة، يمكنك إجراء ذلك من خلال إزالة جميع الأصفار البادئة عند تغيير كل قيمة.

@Composable
fun NoLeadingZeroes() {
    var input by rememberSaveable { mutableStateOf("") }
    TextField(
        value = input,
        onValueChange = { newText ->
            input = newText.trimStart { it == '0' }
        }
    )
}

للتحكّم في موضع المؤشر أثناء تنظيف النص، استخدِم TextFieldValue التفريع الزائد TextField كجزء من الحالة.

أفضل الممارسات حسب الولاية

في ما يلي سلسلة من أفضل الممارسات لتحديد حالة TextField وتعديلها لمنع حدوث مشاكل في الإدخال في تطبيقك.

  • استخدام MutableState لتمثيل حالة TextField: تجنَّب استخدام مصادر البيانات التفاعلية مثل StateFlow لتمثيل حالة TextField، لأنّ هذه البنى قد تؤدي إلى حدوث تأخيرات غير متزامنة.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • تجنُّب التأخيرات لتعديل الولاية: عند الاتصال بـ onValueChange، يمكنك تعديل TextField بشكل متزامن وعلى الفور:

// SignUpViewModel.kt

class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {

    var username by mutableStateOf("")
        private set

    fun updateUsername(input: String) {
        username = input
    }
}

// SignUpScreen.kt

@Composable
fun SignUpScreen(/*...*/) {

    OutlinedTextField(
        value = viewModel.username,
        onValueChange = { username -> viewModel.updateUsername(username) }
        /*...*/
    )
}

  • مكان تحديد الحالة: إذا كانت حالة TextField تتطلّب عمليات تحقّق من صحة منطق النشاط التجاري أثناء الكتابة، من الصحيح رفع الحالة إلى ViewModel. إذا لم يكن الأمر كذلك، يمكنك استخدام عناصر قابلة للإنشاء أو فئة صاحب الدولة كمصدر للحقيقة. لمزيد من المعلومات عن مكان رفع الحالة، اطّلِع على مستندات رفع الحالة.