如何实现现代 Android 导航实现

How to achieve a modern Android Navigation implementation

我想在更新版本 (2.4.0-beta02) 中实现基于 Android 导航组件的导航逻辑,但我遇到了一些问题(或非预期行为)与Android生命周期有关。

我的主要问题是,每次您更改选项卡时,片段都会 完全 重新创建,这意味着 onCreate() 方法被调用每次更改选项卡时。我知道出于性能原因,每次您离开与之关联的选项卡时,片段都会调用 onDestroyView() 方法,然后当您返回该选项卡时,将调用 onCreateView() 方法。实际上我不知道我对导航组件的实现及其行为是否正确,我想知道如何正确实现它。

我的实际实现是这样的:

Gradle 文件:

def navigation = "2.4.0-beta02"
implementation "androidx.navigation:navigation-runtime-ktx:$navigation"
implementation "androidx.navigation:navigation-fragment-ktx:$navigation"
implementation "androidx.navigation:navigation-fragment-ktx:$navigation"
implementation "androidx.navigation:navigation-ui-ktx:$navigation"

持有我标签的activity:

class MainActivity : AppCompatActivity() {

  private lateinit var binding: ActivityMainBinding
  private lateinit var navController: NavController

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment
    navController = navHostFragment.navController

    binding.bottomNav.setupWithNavController(navController)
  }

}

activity布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

          <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
        android:name="androidx.navigation.fragment.NavHostFragment"
            app:navGraph="@navigation/nav_graph"
            app:defaultNavHost="true" />
 
         <com.google.android.material.
            bottomnavigation.BottomNavigationView
            android:id="@+id/bottom_nav"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp"
            android:background="@android:color/white"
            app:itemIconTint="@color/gray"
            app:itemRippleColor="@android:color/transparent"
            app:itemTextColor="@color/gray"
            app:labelVisibilityMode="unlabeled"
            app:menu="@menu/bottom_nav_menu" />
    
</LinearLayout>

图表:

<navigation
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@+id/nav_graph"
  app:startDestination="@+id/home">

  <include app:graph="@navigation/home"/>
  <include app:graph="@navigation/profile"/>

</navigation>

导航首页:

 <navigation
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/home"
  app:startDestination="@+id/homeFragmentNavigation">

  <fragment
      android:id="@+id/homeFragmentNavigation"
android:name="com.tayloring.android.view.page.tabs.HomeFragment"
      android:label="@string/title_home"
      tools:layout="@layout/fragment_home"/>
  </fragment>

</navigation>

二级导航:

  <navigation
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/profile"
    app:startDestination="@+id/profileFragmentNavigation">

    <fragment
      android:id="@+id/profileFragmentNavigation"      
      android:name="com.tayloring.android.view
      .page.user.ProfileFragment"
      android:label="@string/title_profile"
      tools:layout="@layout/fragment_profile"
    </fragment>

  </navigation>

二级片段:

class ProfileFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        println("I'M ALWAYS CALLED")
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_profile, container, false)
    }
}

我也尝试了这个存储库https://github.com/android/architecture-components-samples/tree/master/NavigationAdvancedSample,这是一些现代媒体帖子在谈论导航组件时谈论的例子,但它已经过时并且导航版本较旧。

每次更改选项卡时,导航组件都会调用 onDestroy() 方法,这是正常行为。