在Kotlin中使用setupActionBarWithNavController存在问题。

huangapple go评论74阅读模式
英文:

Issue with setupActionBarWithNavController in Kotlin

问题

I am creating an app with Kotlin and Android Studio. Every dependency is on its latest version. I'm trying to customize the app toolbar's label with Android Jetpack Navigation component label. In my MainActivity.kt I have this code.

// MainActivity.kt

package com.michaelgrigoryan.roomdbapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.navigation.findNavController
import androidx.navigation.ui.setupActionBarWithNavController

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setupActionBarWithNavController(findNavController(R.id.fragment))
    }
}

In my ListFragment

//ListFragment.kt
package com.michaelgrigoryan.roomdbapp.fragments.list

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.michaelgrigoryan.roomdbapp.R
import kotlinx.android.synthetic.main.fragment_list.view.*

class ListFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_list, container, false)

        view.floatingActionButton.setOnClickListener {
            findNavController().navigate(R.id.action_listFragment_to_addFragment)
        }

        return view
    }
}

And in my AddFragment

// AddFragment
package com.michaelgrigoryan.roomdbapp.fragments.add

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.michaelgrigoryan.roomdbapp.R
import kotlinx.android.synthetic.main.fragment_add.view.*

class AddFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_add, container, false)

        view.saveButton.setOnClickListener {
            findNavController().navigate(R.id.action_addFragment_to_listFragment)
        }
        return view
    }
}

My app doesn't even launch. Here's the LOGCAT Output on that error:

2020-10-11 12:03:51.219 11162-11162/com.michaelgrigoryan.roomdbapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.michaelgrigoryan.roomdbapp, PID: 11162
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.michaelgrigoryan.roomdbapp/com.michaelgrigoryan.roomdbapp.MainActivity}: java.lang.IllegalStateException: Activity com.michaelgrigoryan.roomdbapp.MainActivity@6d0f1b does not have a NavController set on 2131230870
    ...

After adding android:name="androidx.navigation.fragment.NavHostFragment" to my fragment in my main layout, I have a new problem. The app loads properly, but now it crashes when I click on the floatingActionButton to change fragments. Here's my logcat output:

2020-10-11 12:36:33.348 11853-11853/com.michaelgrigoryan.roomdbapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.michaelgrigoryan.roomdbapp, PID: 11853
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.material.floatingactionbutton.FloatingActionButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
    ...
英文:

I am creating an app with Kotlin and Android Studio. Every dependency is on it's latest version. I'm trying to customize the app toolbar's label with Android Jetpack Navigation component label. In my MainActivity.kt I have this code.

// MainActivity.kt

package com.michaelgrigoryan.roomdbapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.navigation.findNavController
import androidx.navigation.ui.setupActionBarWithNavController

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setupActionBarWithNavController(findNavController(R.id.fragment))
    }
}

In my ListFragment

//ListFragment.kt
package com.michaelgrigoryan.roomdbapp.fragments.list

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.michaelgrigoryan.roomdbapp.R
import kotlinx.android.synthetic.main.fragment_list.view.*

class ListFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_list, container, false)

        view.floatingActionButton.setOnClickListener {
            findNavController().navigate(R.id.action_listFragment_to_addFragment)
        }

        return view
    }
}

And in my AddFragment

// AddFragment
package com.michaelgrigoryan.roomdbapp.fragments.add

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.michaelgrigoryan.roomdbapp.R
import kotlinx.android.synthetic.main.fragment_add.view.*


class AddFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_add, container, false)

        view.saveButton.setOnClickListener {
            findNavController().navigate(R.id.action_addFragment_to_listFragment)
        }
        return view
    }
}

My app doesn't even launch. Here's the LOGCAT Output on that error

2020-10-11 12:03:51.219 11162-11162/com.michaelgrigoryan.roomdbapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.michaelgrigoryan.roomdbapp, PID: 11162
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.michaelgrigoryan.roomdbapp/com.michaelgrigoryan.roomdbapp.MainActivity}: java.lang.IllegalStateException: Activity com.michaelgrigoryan.roomdbapp.MainActivity@6d0f1b does not have a NavController set on 2131230870
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.IllegalStateException: Activity com.michaelgrigoryan.roomdbapp.MainActivity@6d0f1b does not have a NavController set on 2131230870
        at androidx.navigation.Navigation.findNavController(Navigation.java:61)
        at androidx.navigation.ActivityKt.findNavController(Activity.kt:30)
        at com.michaelgrigoryan.roomdbapp.MainActivity.onCreate(MainActivity.kt:13)
        at android.app.Activity.performCreate(Activity.java:8000)
        at android.app.Activity.performCreate(Activity.java:7984)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

EDIT
<br>
Here are my Layouts<br>
ActivityMain

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.MainActivity&quot;&gt;

    &lt;fragment
        android:id=&quot;@+id/fragment&quot;
        android:layout_width=&quot;409dp&quot;
        android:layout_height=&quot;729dp&quot;
        app:defaultNavHost=&quot;true&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.5&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:navGraph=&quot;@navigation/my_nav&quot;
        tools:layout=&quot;@layout/fragment_list&quot; /&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

fragment_list.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.fragments.list.ListFragment&quot;&gt;

    &lt;androidx.recyclerview.widget.RecyclerView
        android:id=&quot;@+id/recyclerView&quot;
        android:layout_width=&quot;409dp&quot;
        android:layout_height=&quot;729dp&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.5&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot; /&gt;

    &lt;com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id=&quot;@+id/floatingActionButton&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginEnd=&quot;24dp&quot;
        android:layout_marginBottom=&quot;24dp&quot;
        android:clickable=&quot;true&quot;
        android:focusable=&quot;true&quot;
        android:src=&quot;@drawable/ic_baseline_add_24&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot; /&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

fragment_add.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:id=&quot;@+id/addFragment&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.fragments.add.AddFragment&quot;&gt;

    &lt;EditText
        android:id=&quot;@+id/inputFirstName&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginTop=&quot;164dp&quot;
        android:ems=&quot;10&quot;
        android:hint=&quot;First Name&quot;
        android:inputType=&quot;textPersonName&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.497&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot; /&gt;

    &lt;EditText
        android:id=&quot;@+id/inputLastName&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginTop=&quot;15dp&quot;
        android:ems=&quot;10&quot;
        android:hint=&quot;Last Name&quot;
        android:inputType=&quot;textPersonName&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.497&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toBottomOf=&quot;@+id/inputFirstName&quot; /&gt;

    &lt;EditText
        android:id=&quot;@+id/inputAge&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginTop=&quot;16dp&quot;
        android:ems=&quot;10&quot;
        android:hint=&quot;Age&quot;
        android:inputType=&quot;textPersonName&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintHorizontal_bias=&quot;0.497&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toBottomOf=&quot;@+id/inputLastName&quot; /&gt;

    &lt;com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id=&quot;@+id/saveButton&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginBottom=&quot;312dp&quot;
        android:clickable=&quot;true&quot;
        android:focusable=&quot;true&quot;
        android:src=&quot;@drawable/ic_baseline_save_alt_24&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toBottomOf=&quot;@+id/inputAge&quot; /&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

EDIT 2
<br>
After adding android:name=&quot;androidx.navigation.fragment.NavHostFragment&quot; to my fragment in my main layout i have a new problem. The app loads properly but now it crashes when I click on the floatingActionButton to change fragments.
<br>
Here's my logcat output

2020-10-11 12:36:33.348 11853-11853/com.michaelgrigoryan.roomdbapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.michaelgrigoryan.roomdbapp, PID: 11853
    java.lang.NullPointerException: Attempt to invoke virtual method &#39;void com.google.android.material.floatingactionbutton.FloatingActionButton.setOnClickListener(android.view.View$OnClickListener)&#39; on a null object reference
        at com.michaelgrigoryan.roomdbapp.fragments.add.AddFragment.onCreateView(AddFragment.kt:32)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
        at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

答案1

得分: 0

在您的MainActivity布局中使用:

<fragment
    android:id="@+id/fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
英文:

In your MainActivity layout use:

   &lt;fragment
        android:id=&quot;@+id/fragment&quot;
        android:name=&quot;androidx.navigation.fragment.NavHostFragment&quot;

huangapple
  • 本文由 发表于 2020年10月11日 16:09:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/64301874.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定