ببدء مشروع جديد ، قررت أن أحاول التخلي عن ملفات XML تمامًا ، على أساس التنسيقات التي يتم إنشاؤها ، وإنشاء شاشات باستخدام مكتبة Anko. بعد أن اكتسبت القليل من الخبرة في تطوير نظام أندرويد (حوالي عامين) ورمز كتابة أقل خبرة على Kotlin (يزيد قليلاً عن ستة أشهر) ، واجهت على الفور مشكلة تضمين شريط التنقل أسفل تم إنشاؤه بواسطة BottomNavigationView في تطبيق Navigation Architecture Component.
بادئ ذي بدء ، التفتت إلى الإنترنت لإيجاد حل ممكن. لكن كل المقالات التي وجدتها بدرجات متفاوتة من الوضوح تحدثت عن كيفية العمل مع مكونات التنقل ولم يقم أي من (من الذين درست مقالاتهم) بعمله على أنكو. بعد حل المهمة ، أقدم للمجتمع خياري لإنشاء شريط التنقل أسفل.
كل رمز يمكن الاطلاع هنا.
لقد تخطيت مرحلة إنشاء مشروع جديد في Android Studio ، وألاحظ فقط التبعيات التالية للعمل مع Anko و Navigation Architecture Component في build.gradle على مستوى الوحدة النمطية:
implementation "org.jetbrains.anko:anko:$anko_version" implementation "org.jetbrains.anko:anko-constraint-layout:$anko_version" implementation "com.android.support.constraint:constraint-layout:2.0.0-alpha3" implementation 'android.arch.navigation:navigation-fragment:1.0.0-beta02' implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-beta02' implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-beta02' implementation 'com.google.android.material:material:1.0.0'
والخطوة التالية هي إنشاء هيكل التطبيق في المستقبل. لرسم النشاط الرئيسي ، بدلاً من ملف xml ، قم بإنشاء فئة MainActivityUI الموروثة من واجهة AnkoComponent:
class MainActivityUI: AnkoComponent<MainActivity> { override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) { constraintLayout { } } }
في فئة MainActivity ، يتم استبدال setContentView (R.layout.activity_main) بـ MainActivityUI (). SetContentView (هذا).
بعد ذلك ، نقوم بإنشاء أجزاء الحزمة التي تكمن فيها أجزاء الحزمة و ui في وضع الطبقات المسؤولة عن تقديم شاشات الأجزاء المقابلة. هذا هو هيكل المشروع:
fragments ui HomeUI UsersUI DetailsUI MoreUI HomeFragment UsersFragment DetailsFragment MoreFragment
الآن سنتعامل مباشرة مع التنقل وإنشاء شريط التنقل أسفل.
يمكن العثور على وصف تفصيلي لإدراج مكونات التنقل الجديدة ووصف العمل في محرر التنقل في صفحة الوثائق هنا . لإنشاء ملف (رسم بياني) للتنقل بين شاشات التطبيق ، تحتاج إلى إضافة مجلد آخر إلى مجلد res ، أي التنقل وإضافة ملف navigation_graph.xml إليه بالفعل. بالنسبة لهذا المشروع ، سيكون مثل هذا:
<navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation_graph" app:startDestination="@id/homeFragment"> <fragment android:id="@+id/homeFragment" android:name="com.arsinde.ankobottomnavbar.fragments.HomeFragment" android:label="HomeFragment"> <action android:id="@+id/action_homeFragment_to_detailsFragment" app:destination="@id/detailsFragment"/> </fragment> <fragment android:id="@+id/detailsFragment" android:name="com.arsinde.ankobottomnavbar.fragments.DetailsFragment" android:label="DetailsFragment"> <action android:id="@+id/action_detailsFragment_to_usersFragment" app:destination="@id/usersFragment"/> </fragment> <fragment android:id="@+id/usersFragment" android:name="com.arsinde.ankobottomnavbar.fragments.UsersFragment" android:label="UsersFragment"> <action android:id="@+id/action_usersFragment_to_moreFragment" app:destination="@id/moreFragment"/> </fragment> <fragment android:id="@+id/moreFragment" android:name="com.arsinde.ankobottomnavbar.fragments.MoreFragment" android:label="MoreFragment"/> </navigation>
لعرض الشريط نفسه ، تحتاج إلى إنشاء مجلد مورد آخر ، وهو القائمة. أنه يحتوي على الملف المسؤول عن الجزء المرئي من الشريط. هكذا يبدو في هذا المشروع:
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@id/homeFragment" android:icon="@drawable/ic_home" android:title="@string/menu_title_home"/> <item android:id="@id/usersFragment" android:icon="@drawable/ic_users" android:title="@string/menu_title_users"/> <item android:id="@id/detailsFragment" android:icon="@drawable/ic_info" android:title="@string/menu_title_details"/> <item android:id="@id/moreFragment" android:icon="@drawable/ic_more" android:title="@string/menu_title_more"/> </menu>
لقد حان الوقت لوضع كل شيء معًا ونرى كيف يعمل.
أضف حاوية للشظايا في MainActivityUI ، وحدد أيضًا حاوية لشريط التنقل.
constraintLayout { val fragmentContainer = frameLayout { id = R.id.fragment_container }.lparams { width = matchParent height = matchConstraint } val bottomNavigation = bottomNavigation { id = R.id.bottom_nav_view inflateMenu(R.menu.bottom_navigation_menu) } applyConstraintSet { fragmentContainer { connect( START to START of PARENT_ID, END to END of PARENT_ID, TOP to TOP of PARENT_ID, BOTTOM to TOP of R.id.bottom_nav_view ) } bottomNavigation { connect( START to START of PARENT_ID, END to END of PARENT_ID, TOP to BOTTOM of R.id.fragment_container, BOTTOM to BOTTOM of PARENT_ID ) } } }
تجدر الإشارة بشكل خاص إلى أن "bottomNavigation" في هذا المثال هي وظيفة extantion ، والتي لها الشكل التالي:
inline fun ViewManager.bottomNavigation(init: BottomNavigationView.() -> Unit = {}) = ankoView({ BottomNavigationView(it) }, theme = 0, init = init)
الآن في MainActivity ، تحتاج إلى تعريف كائن NavHostFragment (انظر قفص الاتهام):
private val host by lazy { NavHostFragment.create(R.navigation.navigation_graph) }
وفي طريقة onCreate () ، حدد:
supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, host) .setPrimaryNavigationFragment(host) .commit()
اللمسة الأخيرة - أضف إلى onStart () MainActivity كائنًا من فئة NavController ، والذي يسمح لك بالانتقال بين الأجزاء عن طريق اختيار واحد أو آخر من عناصر شريط التنقل:
override fun onStart() { super.onStart() val navController = host.findNavController() findViewById<BottomNavigationView>(R.id.bottom_nav_view)?.setupWithNavController(navController) navController.addOnDestinationChangedListener{_, destination, _ -> val dest: String = try { resources.getResourceName(destination.id) } catch (e: Resources.NotFoundException) { Integer.toString(destination.id) } Log.d("NavigationActivity", "Navigated to $dest") } }
قم بتشغيل التطبيق و vois là ...