لماذا لا أستخدم SharedViewModel للأجزاء؟

هبر ، مرحباً!

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

يوضح الشكل أدناه مخطط التفاعل المكون من 3 أجزاء.

صورة

أولئك. ما نقوم به: في كل جزء نحصل على SharedViewModel لتلك الأجزاء التي نحتاج إلى التفاعل معها ...

وهذا ليس الحل الأفضل ، في رأيي. لان:

  1. *VM. ViewModel View. ViewModel LiveData, View, .. ViewModel - , View.
  2. SharedViewModel — . , SharedViewModel , , . - .
  3. SharedViewModel, . , , .

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

يجلب SharedViewModel الكثير من المشاكل. تبدأ في الخلط ، كل شيء متضخم مع التبعيات ، الرمز معقد. من الأسهل العمل عندما يكون Fragment + ViewModel عبارة عن صندوق أسود.

ما الحل الذي يمكن تقديمه؟

خدمة بسيطة يتفاعل معها كل جزء بطريقته الخاصة.

صورة

يجب تمرير هذه الخدمة داخل كل نموذج ViewModel. بفضل DI والنطاق (Dagger ، Koin ، أي أشخاص آخرين) يمكن القيام بذلك بسهولة وبساطة. إذا كانت الخدمة يجب أن تعيش في سياق نشاط ما ، فقم بإنشائها في نطاق هذا النشاط ثم قم بتمريرها إلى كل نموذج عرض.

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

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

المكافأة: كيف أقوم بإنشاء أجزاء؟


مثل هذا: SomeFragment ()

وماذا عن المعلمات؟

مع ظهور ViewModel ، لا أستخدم المعلمات. لا أنقل أي شيء إلى الجزء عبر الحزمة (لا يزال Android Studio يعرض إنشاء جزء به حجج وإنشاء جزء من خلال الطريقة الثابتة) ، ولا أستخدم Safety NavArgs لمكون التنقل .

كل هذه الأشياء تجعل القطعة مشروطة. لا يمكننا فقط أخذ مثل هذا الجزء وإضافته إلى ViewPager ، على سبيل المثال. يجب على المرء أن يفكر في كيفية تمرير المعلمات. أو مثال آخر: لقد قمت بإنشاء جزء مع معلمات ، والعمل فيه ، وتغيير البيانات ، والجزء يظهر بالفعل شيء آخر. قمنا بتغيير تكوين الجهاز (تم تسليمه) ، وتم إنشاء الجزء من جديد بمعلمات قديمة ، بينما يحتوي ViewModel بالفعل على بيانات أخرى. ويبدأ تحقيق المعلمات ، وما إلى ذلك.

أزلت كل هذا في ViewModel. أستخدم نفس الخدمة التي أمرر من خلالها المعلمات. يعمل مثل Safety NavArgs. تطلب ViewModel معلمات من الخدمة حسب نوع فئة المعلمات. بعد استرداد المعلمة بنجاح ، تقوم الخدمة بحذفها (تعمل مثل Push / Pop).

هذا يحل على الفور مشكلة تغيير التكوين: تم إنشاء الجزء مرة أخرى ، و ViewModel بالفعل مع البيانات الحالية ، كل ما هو مطلوب هو ربطها مع العرض.

هناك أيضًا مشكلة عند تمرير المعلمات من خلال حزمة - هذا هو المبلغ الزائد المسموح به. إذا كان حجم البيانات المنقولة أكثر من 500 كيلو بايت ، فقد يتلف التطبيق بسبب استثناء داخل Binder.java. أدى ذلك إلى إنشاء مكتبات مختلفة تقوم بإرسال المعلمات عبر SD ، وهي ليست سريعة جدًا مقارنة باستخدام ذاكرة الوصول العشوائي.

بشكل عام ، الأدوات رائعة ، كل شيء مرن ، لكنك بحاجة إلى توخي الحذر.

هذا كل شيء ، شكرا للمشاهدة!

All Articles