0Pricing
Android Academy · درس

إدارة حالة النموذج

احتفظ بقيم الحقول وحدّثها باستخدام الحالة

إدارة حالة النموذج درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 4 دروس في المجموع.

من حقل واحد إلى نموذج

يُعدّ حقل النص الواحد سهلًا. أما النموذج الفعلي فيضم عدة حقول: الاسم والبريد الإلكتروني وكلمة المرور وربما مربع اختيار. ستتعلم في هذا الدرس طرقًا واضحة للاحتفاظ بحالة نموذج كامل وتحديثها في Jetpack Compose.

إذا أتقنت ذلك، فستصبح عملية التحقق والإرسال والمعاينات سهلة.

حالات مستقلة متعددة

أبسط طريقة هي استخدام mutableStateOf واحد لكل حقل. يقرأ كل حقل الجزء الخاص به من الحالة ويحدّثه.

وهذا مناسب تمامًا للنماذج الصغيرة التي تضم حقلين أو ثلاثة.

@Composable
fun LoginForm() {
    var email by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }

    Column {
        OutlinedTextField(email, { email = it }, label = { Text("Email") })
        OutlinedTextField(password, { password = it }, label = { Text("Password") })
    }
}

تجميع الحالة في Data Class

كلما كبرت النماذج، أصبحت المتغيرات المتناثرة مربكة. والخيار الأنظف هو نمذجة النموذج بأكمله باعتباره data class غير قابل للتغيير.

تحتفظ بقطعة واحدة من الحالة تحتوي على ذلك الكائن، وتحدّثه باستخدام copy().

data class SignUpState(
    val name: String = "",
    val email: String = "",
    val agreedToTerms: Boolean = false
)

التحديث باستخدام copy()

بما أن كائن الحالة غير قابل للتغيير، فلا تعدّله مباشرةً. بدلًا من ذلك، أنشئ نسخة جديدة غيّرت فيها حقلًا واحدًا، ثم عيّنها مجددًا.

يحافظ ذلك على قابلية التنبؤ بنموذج حالة Compose: فالكائن الجديد يعني لقطة جديدة، مما يؤدي إلى إعادة التركيب.

var form by remember { mutableStateOf(SignUpState()) }

OutlinedTextField(
    value = form.name,
    onValueChange = { form = form.copy(name = it) },
    label = { Text("Name") }
)

نموذج كامل باستخدام فئة بيانات

هنا يدير كائن SignUpState واحد النموذج بالكامل. ويحدّث كل حقل خاصية واحدة عبر copy().

لاحظ مدى سهولة قراءة قيمة النموذج بالكامل في أي وقت: إنها ببساطة form.

var form by remember { mutableStateOf(SignUpState()) }

Column {
    OutlinedTextField(
        value = form.name,
        onValueChange = { form = form.copy(name = it) },
        label = { Text("Name") }
    )
    OutlinedTextField(
        value = form.email,
        onValueChange = { form = form.copy(email = it) },
        label = { Text("Email") }
    )
}

خانات الاختيار ومفاتيح التبديل

ليست كل المدخلات نصية. تعمل Checkbox أو Switch بالطريقة نفسها: قيمة منطقية مع استدعاء ردّ onCheckedChange.

خزّن القيمة المنطقية في حالة النموذج كما تخزّن سلسلة نصية.

var form by remember { mutableStateOf(SignUpState()) }

Row(verticalAlignment = Alignment.CenterVertically) {
    Checkbox(
        checked = form.agreedToTerms,
        onCheckedChange = { form = form.copy(agreedToTerms = it) }
    )
    Text("I agree to the terms")
}

اشتقاق القيم من الحالة

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

استخدم derivedStateOf (أو تعبيرًا بسيطًا) لكي تُحدَّث النتيجة تلقائيًا عند تغيّر النموذج.

var form by remember { mutableStateOf(SignUpState()) }

val canSubmit by remember {
    derivedStateOf {
        form.name.isNotBlank() &&
        form.email.isNotBlank() &&
        form.agreedToTerms
    }
}

Button(onClick = { /* submit */ }, enabled = canSubmit) {
    Text("Sign Up")
}

التعامل مع تغييرات الإعدادات

تحافظ remember على الحالة أثناء عمليات إعادة التركيب، لكنها تفقدها عند تغيير الإعدادات، مثل تدوير الشاشة. للاحتفاظ بالقيم البسيطة أثناء التدوير، استخدم rememberSaveable.

وهي تعمل مباشرةً مع الأنواع البدائية وأنواع Parcelable.

var email by rememberSaveable { mutableStateOf("") }

OutlinedTextField(
    value = email,
    onValueChange = { email = it },
    label = { Text("Email") }
)

رفع حالة النموذج إلى ViewModel

بالنسبة إلى أي نموذج يتجاوز النماذج البسيطة، احتفظ بالحالة في ViewModel. فهي تصمد أمام تغييرات الإعدادات وتُبقي منطق واجهة المستخدم خارج العنصر القابل للتركيب.

يقرأ العنصر القابل للتركيب الحالة ويمرّر الأحداث، بينما يمتلك ViewModel الحقيقة.

class SignUpViewModel : ViewModel() {
    var state by mutableStateOf(SignUpState())
        private set

    fun onNameChange(value: String) {
        state = state.copy(name = value)
    }
}

ربط ViewModel

في العنصر القابل للتركيب، احصل على ViewModel واربط كل حقل بحالته ومعالج الأحداث الخاص به. وبذلك تبقى واجهة المستخدم بسيطة وسهلة الاختبار.

هذه هي البنية الموصى بها لنماذج الإنتاج.

@Composable
fun SignUpScreen(vm: SignUpViewModel = viewModel()) {
    OutlinedTextField(
        value = vm.state.name,
        onValueChange = vm::onNameChange,
        label = { Text("Name") }
    )
}

Kotlin خالصة: تطبيق copy() عمليًا

إن نمط التحديث باستخدام copy() ليس سوى سلوك قياسي لفئة البيانات في Kotlin. وهو يعمل هنا بشكل مستقل حتى تتمكن من رؤية كيف ينتج كل تحديث كائنًا جديدًا تمامًا.

data class SignUpState(
    val name: String = "",
    val email: String = ""
)

fun main() {
    var state = SignUpState()
    state = state.copy(name = "Ada")
    state = state.copy(email = "ada@dev.io")
    println(state)
}

تحقق سريع

لقد صمّمت نموذجك على شكل data class غير قابلة للتغيير ومحتفَظ بها في الحالة. كيف ينبغي تحديث حقل واحد؟

مراجعة

تعلّمت كيفية إدارة حالة النماذج بالكامل:

  • النماذج الصغيرة: كائن mutableStateOf واحد لكل حقل.
  • النماذج الأكبر: كائن data class واحد غير قابل للتغيير، ويُحدَّث باستخدام copy().
  • تتحكم القيم المنطقية في Checkbox وSwitch بالطريقة نفسها التي تتحكم بها النصوص في الحقول.
  • اشتقّ قيمًا مثل «يمكن الإرسال» بدلًا من تخزينها.
  • استخدم rememberSaveable للتعامل مع التدوير، وViewModel للشاشات الفعلية.

التالي: التحقق من صحة المدخلات وعرض الأخطاء المفيدة.

الأسئلة الشائعة

هل درس «إدارة حالة النموذج» مجاني؟

نعم — نص درس «إدارة حالة النموذج» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 4 دروس في المجموع.

ماذا ستتعلم في «إدارة حالة النموذج»؟

احتفظ بقيم الحقول وحدّثها باستخدام الحالة تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟

لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «إدارة حالة النموذج»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟

نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. TextField وإدخال المستخدم
  2. إدارة حالة النموذج
  3. التحقق من صحة الإدخال
  4. خيارات لوحة المفاتيح وإجراءاتها
← العودة إلى Android Academy