英文:
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
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<fragment
android:id="@+id/fragment"
android:layout_width="409dp"
android:layout_height="729dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/my_nav"
tools:layout="@layout/fragment_list" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".fragments.list.ListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="409dp"
android:layout_height="729dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/ic_baseline_add_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_add.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/addFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.add.AddFragment">
<EditText
android:id="@+id/inputFirstName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="164dp"
android:ems="10"
android:hint="First Name"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/inputLastName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:ems="10"
android:hint="Last Name"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/inputFirstName" />
<EditText
android:id="@+id/inputAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:ems="10"
android:hint="Age"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/inputLastName" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="312dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/ic_baseline_save_alt_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/inputAge" />
</androidx.constraintlayout.widget.ConstraintLayout>
EDIT 2
<br>
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.
<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 'void com.google.android.material.floatingactionbutton.FloatingActionButton.setOnClickListener(android.view.View$OnClickListener)' 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:
<fragment
android:id="@+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论