如何实现现代 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() 方法,这是正常行为。
我想在更新版本 (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() 方法,这是正常行为。