【问题标题】:BottomNavigation State gets lost after opening browser and then navigating back打开浏览器然后导航回来后,BottomNavigation 状态会丢失
【发布时间】:2021-07-04 12:16:17
【问题描述】:

今天,我在我的应用程序中发现了一个非常奇怪的错误。它如下:当用户导航到“个人资料屏幕”,然后打开“信息屏幕”,然后单击“agb”,我的应用程序打开浏览器并将用户导航到我的网站。现在奇怪的事情:当用户导航回来(到“信息屏幕”,底部导航表明他当前在主页选项卡上。再次导航回来(到“个人资料屏幕”),然后解决了这个问题。所以它去:

“个人资料屏幕”->“信息屏幕”->单击链接->“打开浏览器” -> 单击返回 -> 状态丢失 -> “信息屏幕” -> 单击返回 -> 状态恢复 -> “配置文件屏幕”。

我添加了一些显示错误的图片(红色表示状态,蓝色表示动作)

导航

  1. Profile Screen (correct state)
  2. Information Screen (correct state)
  3. Browser (Probably state destroyed now)
  4. Information Screen (state destroyed)
  5. Profile Screen (state restored)

片段(信息屏幕)

class UserInformationFragment : Fragment(R.layout.fragment_user_information) {
    private var _binding: FragmentUserInformationBinding? = null
    private val binding: FragmentUserInformationBinding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding  =  FragmentUserInformationBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initUserToolbar()

        with(binding) {
            agbCv.setOnClickListener { startBrowser(INTERNET_AGB) }
            dataProtectionCv.setOnClickListener { startBrowser(INTERNET_DATA_PROTECTION) }
            impressumCv.setOnClickListener { startBrowser(INTERNET_IMPRESSUM) }
        }

    }

    private fun startBrowser(url: String) {
        val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
        startActivity(browserIntent)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

我的一个想法是在用户导航返回后再次手动将状态设置为配置文件屏幕。但这将是一个真正的混乱和奇怪的做法..

导航版

navigation_version = 2.3.5

implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"

【问题讨论】:

  • 我认为你必须使用深层链接!
  • @miladsalimi 打开浏览器?
  • 不,我们设置Intent 用于打开浏览器,从该URL 返回到特定片段,您应该设置深层链接。
  • @miladsalimi 你能给我介绍一个例子吗?我不熟悉深层链接的概念。我特别不知道把这段代码放在哪里(应用程序或活动?)
  • 你在使用导航组件吗?

标签: android kotlin android-architecture-navigation android-navigation


【解决方案1】:

您必须使用深层链接。

假设你有一个片段,你想从浏览器返回给它。

像下面这样添加deep link标签:

mobile_navigation.xml

<fragment
    android:id="@+id/fragment_one"
    android:name="one"
    android:label="one"
     >

    <deepLink
        android:id="@+id/deepLink"
        app:uri="www.Deeplinkuri.com" />
    <action
  

</fragment>

您从后端团队获得 www.Deeplinkuri.com 示例 URI 并添加到您的 fragment。

你应该从服务器端请求一个链接。

现在,当您从浏览器返回时,您可以打开自己的页面。

【讨论】:

  • 对不起,我真的完全不明白这种方法。我唯一想要的就是从我的应用程序打开我的网站,仅此而已。我的信息片段及其 agb 等与我的网站无关(我的片段与网站之间没有联系)。用户首先打开应用程序,然后从他们的我的网站打开,当他返回时,底部导航状态应该会恢复,仅此而已
  • 您能否为“片段一”添加片段代码?
【解决方案2】:

最简单的方法是将您最后选择的状态保存在本地静态变量中,然后 onResume() 从静态变量中应用该选择的状态。

companion object {
    const val LAST_SELECTED_STATE = SHOULD_BE_LAST_SELECTED_MENU_ID
}

override fun onResume() {
    yourBottomNavigation. setSelectedItemId = LAST_SELECTED_STATE
}

【讨论】:

  • 是的,我也是这么想的,但我必须在 4 个不同的片段中这样做
  • 最好提取到 BaseBottomNavigationFragment 并从您要使用的所有片段中扩展它。
  • 但是为什么我必须首先这样做呢?
【解决方案3】:

好的,我已经设法解决了这个问题。该问题与打开浏览器无关,而是与我的活动的重新创建和我的底部导航#menu 的重新膨胀有关。在我有这个之前:

private fun setUpBottomNav(newMenu: Int) {
    with(binding.bottomNavigationView) {
        menu.clear()
        inflateMenu(newMenu)
        setupWithNavController(findNavController(R.id.fragment_container))
        // fix blinking when re selecting bottom nav item
        setOnItemReselectedListener {}
    }
}

问题是setUpBottomNav() 在从浏览器返回到我的应用程序后被调用,因为重新创建了活动。新的解决方案是这样的:

private fun setUpBottomProfile(newMenu: Int) {
    val controller = (supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment).navController

    with(binding.bottomNavigationView) {
        val currentSelectedItem = selectedItemId

        menu.clear()
        inflateMenu(newMenu)

        selectedItemId = currentSelectedItem

        setupWithNavController(controller)
        // fix blinking when re selecting bottom nav item
        setOnItemReselectedListener {}
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 2016-05-30
    • 2022-12-31
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    相关资源
    最近更新 更多