準備實現 iOS 上 UITabBarController + UINavigationController 的功能,這中搭配經常出現在各種類型的 App 上。
在 res 資料夾下建立一個 menu 資料夾,然後在裡面放一個 navigation.xml,定義幾個可以點選的 Item。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
</menu>
實現 navigation 的點擊監控
private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
changeFragmentTo(FragmentType.home)
return@OnNavigationItemSelectedListener true
}
R.id.navigation_dashboard -> {
title = "Dashboard"
changeFragmentTo(FragmentType.dashboard)
return@OnNavigationItemSelectedListener true
}
R.id.navigation_notifications -> {
title = "Notification"
changeFragmentTo(FragmentType.notification)
return@OnNavigationItemSelectedListener true
}
}
false
}
通過 supportFragmentManager 來管理 Fragment
val manager = supportFragmentManager
要切換 Fragment 需要幾個步驟(來自官方文件 in Java)
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Kotlin 的例子
private fun changeFragmentTo(type: FragmentType) {
val transaction = manager.beginTransaction()
when(type) {
FragmentType.home -> {
title = "Home"
val homeFragment = HomeFragment()
transaction.replace(R.id.baseFragment, homeFragment)
}
FragmentType.dashboard -> {
val dashboardFragment = DashboardFragment()
transaction.replace(R.id.baseFragment, dashboardFragment)
}
FragmentType.notification -> {
val notificationFragment = NotificationDashboard()
transaction.replace(R.id.baseFragment, notificationFragment)
}
}
transaction.addToBackStack(null)
transaction.commit()
}
我們在 main 的 layout 中引入 BottomNavigationView
<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/navigation" />
其中我們通過下面的方法引入剛才定義好的 menu(我們在 menu 下,有建立一個 navigation 的文件,並且定義好了幾個 item)
app:menu+@menu/navigaion"
幾個需要注意的地方
顏色的部分可以直接在 <android.support.design.widget.BottomNavigationView /> 下修改
通過在 Activity 中加入
supportActionBar?.setDisplayHomeAsUpEnabled(true)
然後通過 override 方法來接收點擊情況
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.getItemId()) {
// Respond to the action bar's Up/Home button
android.R.id.home -> {
onBackPressed()
return true
}
}
return super.onOptionsItemSelected(item)
}
這裡和 iOS 的 UINavigationController 不太一樣。
通過給 Intent 加 Flag 的方式可以清除其他 Activity 跳到下一個 Activity 上。
val intentHomeActivity = Intent(this, MainActivity::class.java)
intentHomeActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or IntentCompat.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intentHomeActivity)
iOS 通過 CocoaPods 等工具進行依賴包管理而 Android 是通過 Gradle 而 Android 世界裡看起來連官方提供的一些 UI 控件 都會通過 Gradle 加載。
如果不是通過 IDE 來建立 BottomNavigationView,需要手動在 Build.gradle 中的 dependencies 增加依賴
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
</vector>