كيفية التواصل بين الشظايا والنشاط باستخدام ViewModel

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

(النشاط كـ نشاط رئيسي) .passDataToAnotherFragment ()

ما هي المشكلة بهذه الطريقة؟ إنه يربط الجزء مع نشاط معين ، ويقلل من قابليته لإعادة الاستخدام. ثم ما هي الطريقة الموصى بها؟

جوجل يوصي باستخدام واجهة (قبل ViewModel) وثيقة. لهذا علينا أن ننفذ الواجهة في فئة النشاط. ستحتوي الأجزاء الفرعية على مرجع للواجهة المنفذة حسب النشاط. سيتم تمرير البيانات من خلال أساليب واجهة.

تدفق العمل من التواصل باستخدام واجهة

دعنا نفترض سيناريو بسيطًا حيث يوجد لدينا جزءان في نفس النشاط ، أحدهما لإدخال رقم والآخر هو إظهار الرقم المزدوج (2 × إدخال). سيُظهر النشاط أيضًا رسالة مدخلاتك 123 مثل هذا.

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

طريقة سهلة

هنا يأتي ViewModel لإنقاذنا من التعامل مع الكثير من السيناريوهات وتنفيذ الواجهة. نحتاج فقط إلى إنشاء فئة ViewModel وإنشاء مثيل في جزء منه ولكن باستخدام نطاق النشاط بحيث يكون متاحًا لكل جزء من النشاط بما في ذلك النشاط نفسه.

تدفق العمل من التواصل باستخدام ViewModel

إنشاء فئة ViewModel

class SharedViewModel: ViewModel () {
    val inputNumber = MutableLiveData  ()
}

لإرسال أو تمرير البيانات من جزء الإدخال الخاص بنا ، قم بإنشاء ViewModel في نطاق النشاط. للقيام بذلك ، يتعين علينا تمرير مرجع النشاط كوسيطة للأسلوب ViewModelProvides.of (). نوي مجرد تمرير البيانات إلى كائن ViewModel مثل هذا

النشاط؟
    shareViewModel = ViewModelProviders.of (it) .get (SharedViewModel :: class.java)
}

et_input.addTextChangedListener (كائن: TextWatcher {
    تجاوز المتعة بعدTextChanged (p0: Editable؟) {}

    تجاوز المتعة قبلTextChanged (p0: CharSequence ؟، p1: Int، p2: Int، p3: Int) {}

    تجاوز المتعة onTextChanged (txt: CharSequence؟، p1: Int، p2: Int، p3: Int) {
        النص؟
            فار المدخلات = 0
            if (txt.toString (). isNotEmpty ()) {
                الإدخال = txt.toString (). toInt ()
            }

            sharedViewModel؟ .inputNumber؟ .postValue (المدخلات)
        }
    }

في النشاط ، نحتاج فقط إلى إنشاء مثيل لـ ViewModel ومراقبة البيانات المطلوبة مثل هذا

val sharedViewModel = ViewModelProviders.of (this) .get (SharedViewModel :: class.java)

shareViewModel.inputNumber.observe (هذا ، المراقب {
    ذلك؟
        / / افعل بعض الشيء مع الرقم
    }
})

الآن ماذا عن جزء الانتاج؟ يمكننا أن نفعل الشيء نفسه بالنسبة لجزء الإخراج لمراقبة البيانات. لكن ضع في اعتبارك أننا نحتاج إلى إنشاء مثيل ViewModel في نطاق النشاط ، وإلا فإن android سوف ينشئ نسخة منفصلة بدلاً من مشاركة المثيل نفسه ولن نحصل على البيانات.

لشظية الإخراج تفعل ذلك مثل هذا

النشاط؟
    val sharedViewModel = ViewModelProviders.of (it) .get (SharedViewModel :: class.java)

    shareViewModel.inputNumber.observe (هذا ، المراقب {
    ذلك؟
            / / افعل بعض الشيء مع الرقم
        }
    })
}

هذا هو. شفرة المصدر يمكن العثور عليها هنا.

مناقشة StackOverflow

ترميز سعيد