#android #android-fragments #android-viewbinding
Вопрос:
Сообщение об ошибке:
No view found for id 0x7f0a020d (com.samuelriesterer.custombiblereadingplan:id/nav_host_fragment) for fragment FragmentHome{60453b9}
Программа загружает первый фрагмент нормально, но всякий раз, когда фрагмент переключается, она не находит представление фрагмента. Приложение раньше работало, но после перехода на привязку к просмотру оно никогда не переходит к методам onCreateView фрагментов при переключении на любой фрагмент. Он попытается переключиться и вызовет метод onCreate во фрагменте, но больше ничего. Я несколько раз проверял код и сравнивал его с кодом Android для приложения для навигации, и все выглядит законно. Я пробовал аннулировать кэш и перезапуск, но одна и та же ошибка выводится при каждом переключении фрагмента. (Примечание: я реализовал свой собственный стек фрагментов).
В приведенном ниже примере программа сначала нормально загружает FragmentStartup, а затем пытается переключиться на FragmentHome после загрузки данных:
Основной Класс:
class ActivityMain : AppCompatActivity(), InterfaceMain, NavigationView.OnNavigationItemSelectedListener {
private lateinit var binding: ActivityMainBinding
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var fragmentStack: Stack<FragStack>
lateinit var drawerLayout: DrawerLayout
override fun onCreate(savedInstanceState: Bundle?) {
val navView: NavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment)
drawerLayout = binding.drawerLayout
appBarConfiguration = AppBarConfiguration(setOf(R.id.nav_startup, R.id.nav_home, R.id.nav_create_plan, R.id.nav_plans, R.id.nav_read, R.id.nav_settings_text, R.id.nav_settings_system), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
navView.setNavigationItemSelectedListener(this)
GlobalScope.async(Dispatchers.Default) {
setupData()
withContext(Main) {
Logger.log(C.LOG_I, TAG, object {}.javaClass.enclosingMethod?.name ": Going to fragment...")
fragmentStack = Stack()
fragmentStack.add(getFragment(C.FRAG_HOME))
switchFragments(fragmentStack[0])
}
}
}
/*=======================================================================================================*/
override fun getFragment(fragID: Int, vararg id: Int): FragStack {
Logger.log(C.LOG_I, TAG, object {}.javaClass.enclosingMethod?.name ": start, fragID = $fragID")
when (fragID) {
C.FRAG_STARTUP -> {
return FragStack(fragID, FragmentStartup(), -1)
}
C.FRAG_HOME -> {
return FragStack(fragID, FragmentHome(), -1)
}
C.FRAG_CREATE_PLAN -> {
return FragStack(fragID, FragmentCreatePlan(), -1)
}
C.FRAG_PLANS -> {
return FragStack(fragID, FragmentPlans(), -1)
}
C.FRAG_READ -> {
return FragStack(fragID, FragmentRead.newInstance(id[0]), id[0])
}
C.FRAG_DETAILS -> {
return FragStack(fragID, FragmentDetails.newInstance(id[0]), id[0])
}
C.FRAG_ITINERARY -> {
return FragStack(fragID, FragmentItinerary.newInstance(id[0]), id[0])
}
}
return FragStack(fragID, FragmentHome(), -1)
}
/*=======================================================================================================*/
override fun switchFragments(fragStack: FragStack) {
Logger.log(C.LOG_I, TAG, object {}.javaClass.enclosingMethod?.name ": start: frag stack size = ${fragmentStack.size}; from = ${Settings.currentFragment} to = ${fragStack.id}")
// Remove fragment from stack if it is there previously
for(i in (fragmentStack.size - 1) downTo 0) {
if(fragmentStack[i].id == fragStack.id) {
fragmentStack.removeAt(i)
break
}
}
// Push fragment to top of stack:
fragmentStack.push(fragStack)
Settings.currentFragment = fragStack.id
// Remove all fragments from container:
for(fragment in supportFragmentManager.fragments) {
if(fragment != null) {
supportFragmentManager.beginTransaction().remove(fragment).commit()
}
}
Settings.saveState.fragmentList = fragStackToIntArray(fragmentStack)
DatabaseOps.databaseSaveSaveState(Settings.saveState)
// Switch fragments:
this.supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment, fragStack.fragment).commit()
}
}
Фрагмент Дома:
class FragmentHome() : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
Logger.log(C.LOG_I, TAG, object {}.javaClass.enclosingMethod?.name ": start: ")
super.onCreate(savedInstanceState)
setHasOptionsMenu(false)
interfaceMain.changeFragmentTitle(Settings.fragmentTitles[Settings.currentFragment])
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
Logger.log(C.LOG_I, TAG, object {}.javaClass.enclosingMethod?.name ": start")
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
return root
}
}
content_main.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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<fragment
android:id="@ id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>