@kivinus1
учусь

Почему не обнаруживается NavController?

Ошибка:
java.lang.IllegalStateException: View android.widget.FrameLayout{32a4e29 V.E...... ......ID 0,0-0,0} does not have a NavController set

Мой Navigation Graph:
<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/navigation_main_graph"
    app:startDestination="@id/noteListFragment">

    <fragment
        android:id="@+id/noteListFragment"
        android:name="com.kivinus.notee.fragments.NoteListFragment"
        android:label="fragment_note_list"
        tools:layout="@layout/fragment_note_list" >
        <action
            android:id="@+id/action_noteList_to_noteDetail"
            app:destination="@id/noteDetailFragment" />
    </fragment>

    <fragment
        android:id="@+id/noteDetailFragment"
        android:name="com.kivinus.notee.fragments.NoteDetailFragment"
        android:label="fragment_note_detail"
        tools:layout="@layout/fragment_note_detail" >
        <action
            android:id="@+id/action_noteDetail_to_noteList"
            app:destination="@id/noteListFragment" />
    </fragment>

</navigation>


XML стартового фрагмента, из которого я хочу выполнить переход:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/light_yellow"
    tools:context=".fragments.NoteListFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/noteRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</FrameLayout>


Код фрагмента (здесь я и не понимаю как использовать Navigation)
(делаю пременную navController и в onCreateView пытаюсь присвоить ей Navigation.findNavController(fragmentView):
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.kivinus.notee.NoteListFragmentViewModel
import com.kivinus.notee.R
import com.kivinus.notee.localDatabase.NoteEntity


class NoteListFragment : Fragment() {

    private fun quickToast(content: String) {
        Toast.makeText(context, content, Toast.LENGTH_SHORT).show()
    }

    private val viewModel by lazy {
        ViewModelProvider(this).get(NoteListFragmentViewModel::class.java)
    }

    private lateinit var noteRecyclerView: RecyclerView
    private var noteAdapter: NoteAdapter = NoteAdapter()
    private lateinit var navigationController: NavController


override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val fragmentView = inflater.inflate(R.layout.fragment_note_list, container, false)
        noteRecyclerView = fragmentView.findViewById(R.id.noteRecyclerView)
        noteRecyclerView.layoutManager = LinearLayoutManager(context)
        noteRecyclerView.adapter = noteAdapter
        navigationController = Navigation.findNavController(fragmentView)
        return fragmentView
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewModel.noteListLiveData.observe(viewLifecycleOwner, { notes ->
            updateUI(notes)
        })
    }


    private inner class NoteHolder(view: View) :
        RecyclerView.ViewHolder(view), View.OnClickListener {

        private lateinit var note: NoteEntity

        init {
            itemView.setOnClickListener(this)
        }

        //      find required views
        private val titleTextView: TextView = itemView.findViewById(R.id.note_title)
        private val textContentTextView: TextView = itemView.findViewById(R.id.note_text_content)

        //      binding
        fun bind(note: NoteEntity) {
            this.note = note
            this.titleTextView.text = note.title
            this.textContentTextView.text = note.textContent
        }


        override fun onClick(v: View) {
            navigationController.navigate(R.id.action_noteList_to_noteDetail)
        }
    }


    private fun updateUI(notes: List<NoteEntity>?) {
        quickToast(notes.toString())
        noteAdapter.submitList(notes)
    }


    private inner class NoteAdapter :
        ListAdapter<NoteEntity, NoteHolder>(DiffCallback()) {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteHolder {
            val view = layoutInflater.inflate(R.layout.list_item_note, parent, false)
            return NoteHolder(view)
        }

        override fun onBindViewHolder(holder: NoteHolder, position: Int) {
            holder.bind(getItem(position))
        }
    }

    class DiffCallback : DiffUtil.ItemCallback<NoteEntity>() {
        override fun areItemsTheSame(oldItem: NoteEntity, newItem: NoteEntity): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: NoteEntity, newItem: NoteEntity): Boolean {
            return oldItem == newItem
        }
    }

}


Несколько часов пытаюсь понять почему так происходит (никогда раньше не работал с Navigation Component)
Заранее спасибо.
  • Вопрос задан
  • 3122 просмотра
Решения вопроса 1
@kivinus1 Автор вопроса
учусь
Ошибка оказалась просто тупой - на Activity просто был не установлен Navigation Controller, а я в этом даже не сомневался и ошибку искал в коде фрагмента/ XML.

Жаль, что кому то пришлось потратить время на просмотр вопроса
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@foonfyrick
val navController=Navigation.findNavController(this,R.id. navigation_main_graph )
Твой пример немного отличается от моего, у меня было так:
<fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        fab:defaultNavHost="false"
        fab:navGraph="@navigation/nav_graph" />

open class MainActivity : AppCompatActivity() {
    private lateinit var navController:NavController

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

        //creating backArrow
        navController=Navigation.findNavController(this,R.id.fragment)
        NavigationUI.setupActionBarWithNavController(this,navController)
    }
    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp()
    }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы