【问题标题】:kotlin navigation components set title crashkotlin 导航组件设置标题崩溃
【发布时间】:2022-01-18 07:35:35
【问题描述】:

我同时使用navigation 组件和bottomNavigationView。当我多次来回切换选项卡时,我收到了崩溃消息:

 java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    at android.view.ViewGroup.addViewInner(ViewGroup.java:5361)
    at android.view.ViewGroup.addView(ViewGroup.java:5190)
    at android.view.ViewGroup.addView(ViewGroup.java:5162)
    at androidx.appcompat.widget.Toolbar.addSystemView(Toolbar.java:1528)
    at androidx.appcompat.widget.Toolbar.setTitle(Toolbar.java:777)
    at com.atp.newarchitecture.activity.AppActivity.onCreate$lambda-0(AppActivity.kt:119)

代码是:

navController.addOnDestinationChangedListener { _,
                                                        destination,
                                                        argument ->

    binding.toolbar.title = resources.getString(when (destination.id) {
            R.id.fragmentId -> R.string.fragmentTitle
            //... more ids
})

布局文件是:

<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:theme="@style/ToolBarTheme"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navigationIcon="?attr/homeAsUpIndicator" />

        <TextView
            android:id="@+id/selected_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/login_text_input_layout"
            app:layout_constraintBottom_toBottomOf="@+id/toolbar"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="1"
            tools:text="@string/selected_count" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/alert_tip_root"
            android:layout_width="0dp"
            android:layout_height="@dimen/quadruple_margin"
            android:layout_margin="@dimen/default_margin"
            android:visibility="gone"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:visibility="visible" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottom_navigation_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp"
            android:background="?android:attr/windowBackground"
            android:theme="@style/BottomNavigationTheme"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:menu="@menu/bottom_bar" />

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment_activity_main"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="1.0"
            app:navGraph="@navigation/nav_graph" />

        <View
            android:id="@+id/loading_background_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

我知道崩溃消息意味着一个视图应该只有一个父视图,但这里似乎没有 addView。想知道是否每次binding.root.title 分配呼叫addView?有什么帮助吗?谢谢!

编辑

def nav_version = "2.3.5"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
    androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")
    implementation("androidx.navigation:navigation-compose:2.4.0-beta02")

【问题讨论】:

  • 请包括整个堆栈跟踪以及您使用的每个库的版本
  • @ianhanniballake 更新谢谢!
  • 你用那个工具栏打电话给setSupportActionBar()吗?
  • onCreate 的活动 setSupportActionBar(binding.toolbar) 中是的

标签: android kotlin navigation


【解决方案1】:

Navigation UI guide中所述:

警告:如果您将Toolbar 作为参数传递给setSupportActionBar(),则ActionBar 假定拥有该Toolbar 的完全所有权,并且您不得使用任何工具栏API在那次通话之后。

在您致电setSupportActionBar() 的所有情况下都是如此。这意味着直接调用任何Toolbar API(例如setTitle)将破坏该所有权合同并导致此类异常。

相反,您应该:

  1. 根本不要使用setSupportActionBar()。您可以connect a Toolbar to Navigation directly 并升级到AppCompat 1.4.0 以让片段通过MenuHostMenuProvider API 将元素添加到工具栏。

  2. 如果您使用setSupportActionBar(),则需要通过 ActionBar API 设置标题。即调用supportActionBar!!.title = ...

  3. 按照app bar guide 并在导航图 XML 文件中的每个目标上设置一个android:label(即android:label="@string/fragmentTitle")。这将在当前目标更改时自动更新标题(假设您调用了NavigationUI 的适当setup 方法)。这将完全消除使用侦听器的需要,从而允许您完全删除所有代码。

【讨论】:

  • 非常感谢!你是对的。我有 1 NavigationUI.setupWithNavController(binding.toolbar, navController, appBarConfiguration) 2 binding.bottomNavigationView.setupWithNavController(navController) 和 3 setSupportActionBar。我用binding.toolbar 删除了第一个,然后甚至使用binding.toolbar 它可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多