从 Activity 导航到 Fragment 并返回到 Activity 导致 activity 被创建多次
Navigation to Fragment from Activity and back to the Activity is causing the activity to be created multiple times
我遇到的问题好像很奇怪
文字
我有一个带有底部导航菜单的应用程序,其中有 3 个按钮,每个按钮有 3 个片段和一个 MainActivity。当导航到任何这些片段时,一切都按预期工作。
当我从这 3 个片段中的任何一个导航到另一个片段(我们称之为片段 4 或 fr4)时,问题就出现了。
假设我在 fr1,我有一个按钮可以将我带到 fr4。当我返回 fr1(使用 android 后退按钮或按下 fr1 的底部栏按钮)时,我在主要 activity 或 3 个片段中的任何一个中所做的每件事都会重复 2次。如果我再去 fr4,然后回到 fr1,那么一切都重复 3 次,依此类推。
在下面的代码中,fr1 是 fragment_home,fr4 是 fragment_profile。
代码
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var navView: BottomNavigationView
private lateinit var binding: ActivityMainBinding
private val sharedViewModel: SharedViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
navView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
navView.setupWithNavController(navController)
}
override fun onStart() {
super.onStart()
Timber.i("onStart main activity")
}
override fun onStop() {
super.onStop()
Timber.i("onStop main activity")
}
}
framgnet1.kt
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private val sharedViewModel: SharedViewModel by activityViewModels()
private val homeViewModel: HomeViewModel by viewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
binding.lifecycleOwner = viewLifecycleOwner
binding.sharedViewModel = sharedViewModel
binding.homeViewModel = homeViewModel
binding.historyButton.setOnClickListener{
Timber.i("profile button clicked")
}
binding.profileButton.setOnClickListener { view ->
profileButtonClicked(view)
}
return root
}
fun profileButtonClicked() {
Timber.i("profile button clicked")
val action = HomeFragmentDirections.homeToProfileAction()
NavHostFragment.findNavController(this).navigate(action)
}
}
mobile_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<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/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.comp.comp.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/home_to_profile_action"
app:destination="@id/fragment_profile"
app:launchSingleTop="true" />
</fragment>
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.comp.comp.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" >
</fragment>
<fragment
android:id="@+id/navigation_notifications"
android:name="com.comp.comp.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
<fragment
android:id="@+id/fragment_profile"
android:name="com.comp.comp.fragment_profile"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile" />
</navigation>
我尝试在导航操作上切换 launchSingleTop="true"
,但无济于事。
发生以下情况:
- 在主页片段中,如果我按下历史记录按钮,它会打印一次“配置文件按钮已单击”
- 如果我随后点击个人资料按钮,应用会导航到个人资料片段
- 我使用后退按钮或按底部栏上的主页按钮返回主页片段
- 如果我现在按下历史记录按钮,“profile button clicked”会打印两次。
如果我重复上述步骤,那么下次我按历史记录按钮时,它将打印“配置文件按钮已单击”3 次,依此类推。
我也测试过去另一个activity,我的activity运行s中的onStop()
方法也是我去过的两倍个人资料页面曾经。当我回到主 activity 和 onStart()
方法 运行 两次时也是如此。我所做的每件事都会 运行 2 次(或更多),具体取决于我访问个人资料页面的次数。每次我访问同时处于活动状态的个人资料页面时,它似乎都创建了一个主要 activity。有什么想法吗?
我尝试了所有方法都无济于事。然后我意识到,在每次配置更改时,它都会种植一个新的 Jake Wharton 的 Timber 调试树,并且它会记录所有树的所有信息。
希望这可以帮助某人。我的错误是木材刨削在 MainActivity 的 onCreate 中,而它应该在应用程序的 OnCreate 中。
我遇到的问题好像很奇怪
文字
我有一个带有底部导航菜单的应用程序,其中有 3 个按钮,每个按钮有 3 个片段和一个 MainActivity。当导航到任何这些片段时,一切都按预期工作。 当我从这 3 个片段中的任何一个导航到另一个片段(我们称之为片段 4 或 fr4)时,问题就出现了。 假设我在 fr1,我有一个按钮可以将我带到 fr4。当我返回 fr1(使用 android 后退按钮或按下 fr1 的底部栏按钮)时,我在主要 activity 或 3 个片段中的任何一个中所做的每件事都会重复 2次。如果我再去 fr4,然后回到 fr1,那么一切都重复 3 次,依此类推。
在下面的代码中,fr1 是 fragment_home,fr4 是 fragment_profile。
代码
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var navView: BottomNavigationView
private lateinit var binding: ActivityMainBinding
private val sharedViewModel: SharedViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
navView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
navView.setupWithNavController(navController)
}
override fun onStart() {
super.onStart()
Timber.i("onStart main activity")
}
override fun onStop() {
super.onStop()
Timber.i("onStop main activity")
}
}
framgnet1.kt
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private val sharedViewModel: SharedViewModel by activityViewModels()
private val homeViewModel: HomeViewModel by viewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
binding.lifecycleOwner = viewLifecycleOwner
binding.sharedViewModel = sharedViewModel
binding.homeViewModel = homeViewModel
binding.historyButton.setOnClickListener{
Timber.i("profile button clicked")
}
binding.profileButton.setOnClickListener { view ->
profileButtonClicked(view)
}
return root
}
fun profileButtonClicked() {
Timber.i("profile button clicked")
val action = HomeFragmentDirections.homeToProfileAction()
NavHostFragment.findNavController(this).navigate(action)
}
}
mobile_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<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/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.comp.comp.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/home_to_profile_action"
app:destination="@id/fragment_profile"
app:launchSingleTop="true" />
</fragment>
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.comp.comp.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" >
</fragment>
<fragment
android:id="@+id/navigation_notifications"
android:name="com.comp.comp.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
<fragment
android:id="@+id/fragment_profile"
android:name="com.comp.comp.fragment_profile"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile" />
</navigation>
我尝试在导航操作上切换 launchSingleTop="true"
,但无济于事。
发生以下情况:
- 在主页片段中,如果我按下历史记录按钮,它会打印一次“配置文件按钮已单击”
- 如果我随后点击个人资料按钮,应用会导航到个人资料片段
- 我使用后退按钮或按底部栏上的主页按钮返回主页片段
- 如果我现在按下历史记录按钮,“profile button clicked”会打印两次。
如果我重复上述步骤,那么下次我按历史记录按钮时,它将打印“配置文件按钮已单击”3 次,依此类推。
我也测试过去另一个activity,我的activity运行s中的onStop()
方法也是我去过的两倍个人资料页面曾经。当我回到主 activity 和 onStart()
方法 运行 两次时也是如此。我所做的每件事都会 运行 2 次(或更多),具体取决于我访问个人资料页面的次数。每次我访问同时处于活动状态的个人资料页面时,它似乎都创建了一个主要 activity。有什么想法吗?
我尝试了所有方法都无济于事。然后我意识到,在每次配置更改时,它都会种植一个新的 Jake Wharton 的 Timber 调试树,并且它会记录所有树的所有信息。 希望这可以帮助某人。我的错误是木材刨削在 MainActivity 的 onCreate 中,而它应该在应用程序的 OnCreate 中。