Can anyone help me find the error in this code as it says, it cannot inflate the fragment in the main activity, and by the way, I am new to android. I tried to change the inflating line of code to be the last one in the onCreate function, but it did nothing.
Here is the Code of the activity:
package com.voicenoteinc.tictactou
import android.graphics.Color
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.app.FragmentActivity
import android.support.v4.app.Fragment
import android.view.View
import android.widget.Button
import kotlinx.android.synthetic.main.fragment_test.*
class MainActivity : AppCompatActivity() {
var tstFragment:TestFragment? = null
val manager = supportFragmentManager
val FRAGMENT_TAG = "fragment_tag"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (manager.findFragmentByTag(FRAGMENT_TAG) != null) {
tstFragment = manager.findFragmentByTag(FRAGMENT_TAG) as TestFragment
}
if (tstFragment == null) {
tstFragment = TestFragment()
manager.beginTransaction().add(tstFragment, FRAGMENT_TAG).commit()
}
}
}
The XML activity:
<?xml version="1.0" encoding="utf-8"?>
<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:gravity="center"
tools:context="com.voicenoteinc.tictactou.MainActivity">
<fragment
android:id="#+id/fragment"
android:name="com.voicenoteinc.tictactou.TestFragment"
android:tag="fragment_tag"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#layout/fragment_test" />
</LinearLayout>
The fragment class:
package com.voicenoteinc.tictactou
import android.content.Context
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.fragment_test.*
class TestFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
bu.setOnClickListener { bu.setBackgroundColor(Color.CYAN) }
return inflater!!.inflate(R.layout.fragment_test, container, false)
}
}// Required empty public constructor
There are two ways to add a Fragment to an Activity.
Add it statically like you have done here:
<fragment
android:id="#+id/fragment"
android:name="com.voicenoteinc.tictactou.TestFragment"
android:tag="fragment_tag"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#layout/fragment_test" />
Add it dynamically to a ViewGroup like this:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
It seems you have attempted to do both here. So you can safely remove all of this code assuming you want to add it statically:
// Remove all this code
if (manager.findFragmentByTag(FRAGMENT_TAG) != null) {
tstFragment = manager.findFragmentByTag(FRAGMENT_TAG) as TestFragment
}
if (tstFragment == null) {
tstFragment = TestFragment()
manager.beginTransaction().add(tstFragment, FRAGMENT_TAG).commit()
}
Explained in detail here under Adding a fragment to an activity
Related
I've worked on the FragmentContainerView activity with some fragments, in that fragment, I want to use Compose alongside XML using ComposeViewin the first fragment, but when I try to navigate from the second fragment and back to the first fragment, the component from ComposeView was disappeared.
I've set up a fragment with FragmentContainerView using the replace strategy and I put the fragment inside the list like usual, and I have no idea what happens with this situation.
You can watch in this video
also this is my code
NavigationActivity.kt
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri
import androidx.navigation.NavDeepLinkRequest
import androidx.navigation.Navigation
import androidx.navigation.findNavController
import id.derysudrajat.inlinebinding.viewBinding
import id.derysudrajat.library.R
import id.derysudrajat.library.databinding.ActivityNavigationBinding
class NavigationActivity : AppCompatActivity() {
private val binding by viewBinding(ActivityNavigationBinding::inflate)
private val listOfFragment = listOf(FragmentMainNav(), FragmentDetailNav())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.btnHome.setOnClickListener{
replace(HOME_NAV)
}
binding.btnDetail.setOnClickListener{
replace(DETAIL_NAV)
}
Navigation.createNavigateOnClickListener(R.id.fragmentDetailNav, null)
}
private fun replace(nav: String) {
supportFragmentManager
.beginTransaction()
.replace(
binding.fragmentContainerView.id,
if (nav == HOME_NAV) listOfFragment[0] else listOfFragment[1]
)
.commit()
}
companion object {
const val HOME_NAV = "home_nav"
const val DETAIL_NAV = "detail_nav"
}
}
FragmentMainNav.kt
import android.os.Bundle
import android.view.View
import androidx.compose.material3.Text
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.lifecycle.Lifecycle
import androidx.navigation.findNavController
import id.derysudrajat.inlinebinding.BindingFragment
import id.derysudrajat.inlinebinding.viewBinding
import id.derysudrajat.library.R
import id.derysudrajat.library.databinding.FragmentNavMainBinding
class FragmentMainNav : BindingFragment<FragmentNavMainBinding>() {
override val binding by viewBinding(FragmentNavMainBinding::inflate)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.textMain.text = "Fragment Main"
binding.composeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
Text(text = "This is Compose")
}
}
}
}
fragment_nav_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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/text_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment Main"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.compose.ui.platform.ComposeView
android:id="#+id/compose_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
FragmentDetailNav.kt
import android.os.Bundle
import android.view.View
import id.derysudrajat.inlinebinding.BindingFragment
import id.derysudrajat.inlinebinding.viewBinding
import id.derysudrajat.library.databinding.FragmentNavDetailBinding
import id.derysudrajat.library.databinding.FragmentNavMainBinding
class FragmentDetailNav : BindingFragment<FragmentNavDetailBinding>() {
override val binding by viewBinding(FragmentNavDetailBinding::inflate)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.textDetail.text = "Detail Navigation"
}
}
fragment_nav_detail.kt
<?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">
<TextView
android:id="#+id/text_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Detail Navigation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I've tried using different ways like changing ViewCompositionStrategy and it still not working, I expected to show ComposeView still show when the fragment was replaced and back, btw the compose that I was tried is from compose BOM 2022.10.00 - 2023.01.00 but still disappeared when the fragment was replaced.
I think you could move the binding.composeView.apply {} block from onViewCreated to onCreateView as shown by provided sample in official documentation here. I've tested it using compose bom 2023.01.00 and plain ViewBinding and it works fine. So the HomeFragment would be like this:
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val view = binding.root
binding.composeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
Text(text = "This is Compose")
}
}
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
As additional note, i don't think the Navigation.createNavigateOnClickListener() is necessary and could just be removed.
I need to create 2 fragments and 2 button in first fragment one which will close current fragment and start another, and second which will close app at all, what i'm doing wrong(each fragment in different holders)?
First fragment opens well, but when i click on buttons in first activity, they don't working at all.
How can i write this rightway?
MainActivity.kt
package com.example.webviewapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager
.beginTransaction()
.replace(R.id.fullcreen_holder, start_fragment.newInstance())
.commit()
}
}
start_fragment.kt
package com.example.webviewapp
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
class start_fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.layout_start_fragment, container, false)
val agreeButton: Button = view.findViewById(R.id.privacy_agree)
val declineButton: Button = view.findViewById(R.id.privacy_decline)
agreeButton.setOnClickListener{
requireActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.webview_holder, webview_fragment())
.hide(start_fragment())
.commit();
}
declineButton.setOnClickListener{
android.os.Process.killProcess(android.os.Process.myPid())
}
return inflater!!.inflate(R.layout.layout_start_fragment, container, false)
}
companion object {
#JvmStatic
fun newInstance() = start_fragment()
}
}
Let's crate an android resouse directoty. That directory name is navigation.
After that we create navigation resouse file. That file will have name as nav_graph.xml
The next we put it in your activity_main.xml
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph" />
In nav_graph.xml we add destinations. It looks like
<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/nav_host"
app:startDestination="#id/oneFragment">
<fragment
android:id="#+id/oneFragment"
android:name="com.uogames.androidjun.OneFragment"
android:label="OneFragment"
tools:layout="#layout/fragment_one" >
</fragment>
<fragment
android:id="#+id/twoFragment"
android:name="com.uogames.androidjun.TwoFragment"
android:label="TwoFragment"
tools:layout="#layout/fragment_two" />
</navigation>
Then when you start application you will start whith OneFragment.
And if you call findNavController().navigate(R.id.to_twoFragment)
you will see second fragment. You can read about it here.
Also you need dependencies
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.4.2'
If you want to close application just call it requireActivity().finishAndRemoveTask()
This question already has answers here:
ViewPager and RecyclerView issue with fragment transition
(2 answers)
Closed 1 year ago.
ViewPager2 Caused by IllegalStateException FragmentManager is already executing transactions
Replicated Crash : while rotating screen
How to fix Viewpager2 FragmentManager is already executing transactions?
Full source code:
https://github.com/stevdza-san/ViewPager2-with-Navigation-Component-TestApp
ViewPagerFragment.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.test.zigmaster.databinding.FragmentViewPagerBinding
class ViewPagerFragment : Fragment() {
var binding : FragmentViewPagerBinding?= null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
// val view = inflater.inflate(R.layout.fragment_view_pager, container, false)
binding = FragmentViewPagerBinding.inflate(inflater)
val fragmentList = arrayListOf<Fragment>(
FirstScreen(),
SecondScreen(),
ThirdScreen()
)
val adapter = ViewPagerAdapter(
fragmentList,
requireActivity().supportFragmentManager,
lifecycle
)
binding!!.viewPager.adapter = adapter
return binding!!.root
}
override fun onDestroyView() {
super.onDestroyView()
binding=null
}
}
ViewPagerAdapter.kt
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
class ViewPagerAdapter(
list: ArrayList<Fragment>,
fm: FragmentManager,
lifecycle: Lifecycle
) : FragmentStateAdapter(fm, lifecycle) {
private val fragmentList = list
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
return fragmentList[position]
}
}
fragment_view_pager.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=".ui.app_intro.ViewPagerFragment">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>
FirstScreen.kt
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.viewpager2.widget.ViewPager2
import com.test.zigmaster.R
import com.test.zigmaster.databinding.FragmentFirstScreenBinding
class FirstScreen : Fragment() {
private var binding : FragmentFirstScreenBinding?= null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentFirstScreenBinding.inflate(inflater)
val viewPager = activity?.findViewById<ViewPager2>(R.id.viewPager)
binding!!.next.setOnClickListener {
viewPager?.currentItem = 1
}
return binding!!.root
}
override fun onDestroyView() {
super.onDestroyView()
binding=null
}
Change view.viewPager.adapter = adapter to
Handler(Looper.getMainLooper()).post {
view.viewPager.adapter = adapter
}
in https://github.com/stevdza-san/ViewPager2-with-Navigation-Component-TestApp/blob/master/app/src/main/java/com/jovanovic/stefan/mytestapp/onboarding/ViewPagerFragment.kt
I am trying to use the YouTubePlayerSupportFragment inside my own fragment that I created. When trying to add it into the childFragmentManager's fragment transaction, I get a type cast error saying that the object's type needs to be Fragment and not YouTubePlayerSupportFragment. I am adding it into the fragment transaction so that I can choose when to hide or show the fragment. Everything I have seen online and written in Java works the same way my code works unless it has something to do with Kotlin?
Fragment.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="#+id/youtube_player_fragment"
android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment.kt
import android.os.Bundle
import android.text.SpannableString
import android.text.style.BulletSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.google.android.youtube.player.YouTubeInitializationResult
import com.google.android.youtube.player.YouTubePlayer
import com.google.android.youtube.player.YouTubePlayerSupportFragment
class ExpandedItemFragment(private val hasVideo: Boolean) : Fragment(), YouTubePlayer.OnInitializedListener {
private lateinit var mosquitoVideo: YouTubePlayerSupportFragment
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(
R.layout.expanded_item, container, false
)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
initializeLayout()
}
private fun initializeLayout() {
mosquitoVideo = YouTubePlayerSupportFragment.newInstance()
childFragmentManager.beginTransaction()
.add(R.id.youtube_player_fragment, mosquitoVideo) //Type cast error happening here
if (hasVideo) {
mosquitoVideo.initialize(getString(R.string.google_api_key), this)
}
}
override fun onInitializationSuccess(
provider: YouTubePlayer.Provider,
youTubePlayer: YouTubePlayer,
b: Boolean
) {
if (!b) {
youTubePlayer.cueVideo("rD8SmacBUcU")
}
}
override fun onInitializationFailure(
provider: YouTubePlayer.Provider,
youTubeInitializationResult: YouTubeInitializationResult
) {
Toast.makeText(activity, "Youtube video failed to play", Toast.LENGTH_SHORT).show()
}
Try to use this component here it implements web frame
https://github.com/PierfrancescoSoffritti/android-youtube-player
add to build.grandle
dependencies {
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5'
}
add to you XML
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="#+id/youtube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
load video
YouTubePlayerView youTubePlayerView = findViewById(R.id.youtube_player_view);
youTubePlayerView.addYouTubePlayerListener(new AbstractYouTubePlayerListener() {
#Override
public void onReady(#NonNull YouTubePlayer youTubePlayer) {
String videoId = "rD8SmacBUcU";
youTubePlayer.loadVideo(videoId, 0);
}
});
I'm trying to set navController to bottomNavigation, but it's requires activity, the problem is my borromNavigation hosted in fragment, so i don't have activity instance.
I've tried
bottom_nav_view.setupWithNavController(findNavController())
and:
val host = Navigation.findNavController(this.activity!!.parent, R.id.my_nav_host_fragment)
bottom_nav_view.setupWithNavController(host)
home_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.fragments.home.HomeFragment">
<fragment
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/main_navigation"
app:defaultNavHost="true"
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:id="#+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/bottom_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
So, I need somehow take my_nav_host_fragment from my home_fragment.xml in HomeFragment.kt
HomeFragment.kt
package andy.schedulekpi.ui.fragments.home
import androidx.lifecycle.ViewModelProviders
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.setupWithNavController
import andy.schedulekpi.R
import andy.schedulekpi.ui.fragments.start.StartFragmentDirections
import kotlinx.android.synthetic.main.home_fragment.*
class HomeFragment : Fragment() {
companion object {
fun newInstance() = HomeFragment()
}
private lateinit var viewModel: HomeViewModel
private lateinit var host : NavController
val safeArgs : HomeFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.home_fragment, container, false)
//host = Navigation.findNavController(this.activity!!.parent, R.id.my_nav_host_fragment)
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
// TODO: Use the ViewModel
Toast.makeText(this.context, safeArgs.currentWeek.toString(), Toast.LENGTH_SHORT).show()
//val navController = Navigation.findNavController(activity!!.parent, R.id.my_nav_host_fragment) - don't work
//val host = Navigation.findNavController() -ERROR
// bottom_nav_view.setupWithNavController(findNavController()) -ERROR
}
}
bottom_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:icon="#drawable/ic_schedule"
android:id="#+id/scheduleFragment"
android:title="Schedule"/>
<item
android:icon="#drawable/ic_database"
android:id="#+id/archiveFragment"
android:title="Database"/>
<item
android:id="#+id/teachersFragment"
android:icon="#drawable/ic_teachers"
android:title="Teachers"/>
<item
android:id="#+id/settingsFragment"
android:icon="#drawable/ic_settings_"
android:title="Settings"/>
</menu>
main_navigation.xml:
<?xml version="1.0" encoding="utf-8"?>
<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/main_navigation"
app:startDestination="#id/scheduleFragment">
<fragment
android:id="#+id/scheduleFragment"
android:name="andy.schedulekpi.ui.fragments.schedule.ScheduleFragment"
android:label="schedule_fragment"
tools:layout="#layout/schedule_fragment"/>
<fragment
android:id="#+id/archiveFragment"
android:name="andy.schedulekpi.ui.fragments.archive.ArchiveFragment"
android:label="archive_fragment"
tools:layout="#layout/archive_fragment"/>
<fragment
android:id="#+id/teachersFragment"
android:name="andy.schedulekpi.ui.fragments.teachers.TeachersFragment"
android:label="teachers_fragment"
tools:layout="#layout/teachers_fragment"/>
<fragment
android:id="#+id/settingsFragment"
android:name="andy.schedulekpi.ui.fragments.settings.SettingsFragment"
android:label="settings_fragment"
tools:layout="#layout/settings_fragment"/>
</navigation>
I expected to handle bottomNavigation from fragment, but now i clicked on menu items and nothing happend or error.
In HomeFragment to set navController on BottomNavigationView:
import androidx.navigation.findNavController
Navigation.setViewNavController(bottom_nav_view, activity!!.findNavController(R.id.my_nav_host_fragment))
then when u want get navController from bottom_nav_view:
bottom_nav_view.findNavController()
As said Artur Gniewowski, in HomeFragment in onActivityCreated I need just add
bottom_nav_view.setupWithNavController(activity!!.findNavController(R.id.my_nav_host_fragment))
So, now in HomeFragment i have:
package andy.schedulekpi.ui.fragments.home
import androidx.lifecycle.ViewModelProviders
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.Navigation
import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import androidx.navigation.ui.setupWithNavController
import andy.schedulekpi.R
import kotlinx.android.synthetic.main.home_fragment.*
import kotlinx.android.synthetic.main.home_fragment.view.*
class HomeFragment : Fragment() {
companion object {
fun newInstance() = HomeFragment()
}
private lateinit var viewModel: HomeViewModel
val safeArgs : HomeFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.home_fragment, container, false)
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
// TODO: Use the ViewModel
//Navigation.setViewNavController(bottom_nav_view, activity!!.findNavController(R.id.my_nav_host_fragment))
bottom_nav_view.setupWithNavController(activity!!.findNavController(R.id.my_nav_host_fragment))
Toast.makeText(this.context, safeArgs.currentWeek.toString(), Toast.LENGTH_SHORT).show()
}
}
Thanks to Artur Gniewowski.