16 نصائح لتطوير android في Kotlin. الجزء 2

مرحبا بالجميع. تحسبا لبدء الدورة التدريبية الأساسية حول تطوير Android ، نواصل تبادل المواد المفيدة.



قبل قراءة هذه النصائح ، يجب عليك قراءة وثائق Kotlin وتعلم اللغة بنفسك على try.kotlinlang.org . نظرًا لأن هذه النصائح تهدف بشكل خاص إلى استخدام Kotlin في سياق تطوير Android ، يجب أن تكون لديك أيضًا تجربة مع Android SDK. يُنصح أيضًا بالتعرف على المكوِّن الإضافي Kotlin واستخدام Kotlin مع Android Studio من JetBrains (منشئو Kotlin)



اقرأ الجزء الأول

وصف الكائنات


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

على سبيل المثال ، إذا كان لدي فئة فائدة مع أساليب ثابتة مرتبطة بالسلسلة ، وأرغب في الوصول إلى التطبيق بأكمله ، يمكنك القيام بذلك:

 package com.myapps.example.util import android.os.Handler import android.os.Looper // ,   ,    object ThreadUtil { fun onMainThread(runnable: Runnable) { val mainHandler = Handler(Looper.getMainLooper()) mainHandler.post(runnable) } } 

يمكن استدعاء ThreadUtil لاحقًا بنفس طريقة استدعاء أسلوب الفصل الثابت:

 ThreadUtil.onMainThread(runnable) 

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

 iewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) {} override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageSelected(position: Int) { bindUser(position) } }); 

كلاهما يقومان بنفس الشيء - يقومان بإنشاء مثيل واحد من الفصل ككائن معلن.

دعم الكائنات


للوهلة الأولى ، ليس لدى Kotlin متغيرات وطرق ثابتة. لا توجد مثل هذه المفاهيم في هذه اللغة ، ولكن هناك مفهوم للأشياء المساعدة. إنها كائنات مفردة في فصل دراسي تحتوي على طرق ومتغيرات يمكنك الوصول إليها بطريقة ثابتة. يسمح كائن مصاحب لبعض الثوابت والأساليب ، على غرار الفئات الثابتة في جافا. مع ذلك ، يمكنك اتباع نمط مقتطف newInstance .

ألقِ نظرة على الكائن المصاحب بأبسط أشكاله:

 class User { companion object { const val DEFAULT_USER_AGE = 30 } } //      : user.age = User.DEFAULT_USER_AGE 


على Android ، نستخدم طرقًا ومتغيرات ثابتة لإنشاء مصانع ثابتة للشظايا. على سبيل المثال:

 class ViewUserActivity : AppCompatActivity() { companion object { const val KEY_USER = "user" fun intent(context: Context, user: User): Intent { val intent = Intent(context, ViewUserActivity::class.java) intent.putExtra(KEY_USER, user) return intent } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_cooking) val user = intent.getParcelableExtra<User>(KEY_USER) //... } } 

يشبه إنشاء نية إجراء مماثل في Java:

 val intent = ViewUserActivity.intent(context, user) startActivity(intent) 

يعد هذا النمط جيدًا لأنه يقلل من احتمالية عدم توفر بيانات Intent أو Fragment للبيانات الضرورية لعرض أي محتوى محدد من قبل المستخدم أو أي محتوى آخر. الكائنات المصاحبة هي وسيلة للحفاظ على نموذج الوصول الثابت في Kotlin ويجب استخدامها للتعويض عن عدم وجود فئات.

الثوابت العالمية


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

 package com.myapps.example import android.support.annotation.StringDef //   ,  ! const val PRESENTATION_MODE_PRESENTING = "presenting" const val PRESENTATION_MODE_EDITING = "editing" 

ثم يمكن استخدامها كثوابت في أي مكان في المشروع:

 import com.savvyapps.example.PRESENTATION_MODE_EDITING val currentPresentationMode = PRESENTATION_MODE_EDITING 

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

توسع


الإضافات مفيدة لأنها تتيح لك إضافة وظائف الفئة دون أن ترثها. على سبيل المثال ، كيفية إضافة بعض الأساليب إلى hideKeyboard() مثل hideKeyboard() ؟ باستخدام الملحقات ، يمكنك القيام بذلك بسهولة:

 fun Activity.hideKeyboard(): Boolean { val view = currentFocus view?.let { val inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager return inputMethodManager.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS) } return false } 

الإضافات مفيدة من حيث أنها:

  • المساعدة في تحسين قراءة التعليمات البرمجية
  • القضاء على الحاجة إلى إنشاء فئات الأداة وطرق.

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

 class Article(val title: String, val numberOfViews: Int, val topic: String) 

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

 fun Article.isArticleRelevant(user: User): Boolean { return user.favoriteTopics.contains(topic) } 

هذه طريقة سهلة حاليًا للتحقق من وجود موضوع مقالة في قائمة الموضوعات المفضلة لديك.

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

Source: https://habr.com/ru/post/ar480534/


All Articles