Android Add fragment within a fragment - android

I'm trying to add a fragment within a subclass of DialogFragment. I have a FrameLayout with an id pref_container that I want to replace with a fragment called settingsFragment.
The problem is that fragmentTransaction can't find R.id.pref_container, I don't know if this is because pref_container is only inflated in onCreateView rather than being part of the activity?
I am very new to Android programming, so thank you for your time.
class QuestionnaireDialog : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
this.setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.questionnaire_layout,container,true)
val settingsFragment = ExercisesOnlySettingsFragment()
val ft = fragmentManager?.beginTransaction()
/// **** Here fragmentTransaction can't find R.id.pref_container because it's inflated later and not loaded as part of the activity? ****
ft?.add(R.id.pref_container, settingsFragment)
ft?.commit()
return view
}
}
The runtime error I get is
No view found for id 0x7f09009c (com.lescadeaux.kegel:id/pref_container) for fragment ExercisesOnlySettingsFragment{4ba4b89 #1 id=0x7f09009c}
Here is relavent part of my XML for questionnaire_layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
android:id="#+id/questionnaireLayout"
android:background="#android:color/background_light">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView"
app:layout_constraintTop_toBottomOf="#+id/textView5"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="#+id/button"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- RELAVENT PART -->
<FrameLayout
android:layout_width="300dp"
android:layout_height="match_parent"
android:id="#+id/pref_container">
</FrameLayout>
<!-- RELAVENT PART -->
</LinearLayout>
</HorizontalScrollView>
</android.support.constraint.ConstraintLayout>

Please try to use getChildFragmentManager() (or its kotlin equivalent) instead of getFragmentManager() you are using - it will work.

Related

Set a Fragment inside a Fragment

I have seen similar questions here, but none of them helps.
I have MainActivity and a few Fragments which works fine, but I want to set one fragment inside of another.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomMenu)
val hostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainer) as NavHostFragment
val navigationController = hostFragment.navController
bottomNavigationView.setupWithNavController(navigationController)
setupActionBarWithNavController(navigationController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragmentContainer)
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
Parent Fragment:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_main, container, false)
incomeButton = view.findViewById(R.id.addIncomeButton)
expenseButton = view.findViewById(R.id.addExpenseButton)
val childFragment: Fragment = ChartFragment()
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
transaction.replace(R.id.childFragment, childFragment).commit()
return view
}
Child Fragment:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return ComposeView(requireContext()).apply {
setContent {
Text(
text = "here is another important code",
fontSize = 28.sp
)
}
}
The layouts for Activity:
<?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">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomMenu"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:menu="#menu/bottom_menu" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentContainer"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="475dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottomMenu"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_map" />
</androidx.constraintlayout.widget.ConstraintLayout>
The layouts for Fragment:
<?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.MainFragment">
<Button
android:id="#+id/addIncomeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="21dp"
android:layout_marginBottom="21dp"
android:backgroundTint="#color/primary"
android:text="#string/addIncomeButton"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="#+id/addExpenseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="21dp"
android:layout_marginBottom="10dp"
android:backgroundTint="#color/red"
android:text="#string/addExpenseButton"
app:layout_constraintBottom_toTopOf="#+id/addIncomeButton"
app:layout_constraintEnd_toEndOf="parent" />
<FrameLayout
android:id="#+id/forChart"
android:layout_width="match_parent"
android:layout_height="350dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The most of the same questions' solvations say to use childFragmentManager so do I but it doesn't work.
I get an error java.lang.IllegalArgumentException: No view found for id 0x7f08023f.
I guess I do not understand something, but I can't realize what.
Thank you!
Seems that you're mixing the ids of the container for the transaction - that's also what the error says. You're trying to put the ChartFragment into a container with R.id.childFragment id:
transaction.replace(R.id.childFragment, childFragment).commit()
And from what I see in the MainFragment layout, the container id is R.id.forChart. Try changing it to this:
transaction.replace(R.id.forChart, childFragment).commit()

Talkback doesn't focus new fragment after second navigation

I have an app using Android Navigation (single activity many fragments).
When launched, the app displays a loading screen, an optional "news"-type screen which returns the user to the home screen when they're done, then a home screen.
However, I'm having trouble getting accessibility to pick up the home screen. When the news screen isn't shown, it'll get focused fine, but when it is included, the home screen will not receive focus, which seems to remain on the loading screen.
I've been able to reproduce this in a minimal example, with screens "Loading", "A", and "B". The app behaviour here is:
Launch on Main Fragment
wait 5 seconds, navigate to fragment A
user presses "continue"
return to Main Fragment
Wait 5 seconds, navigate to fragment B
After each navigation, I'd expect the text element to be focused, and read out. However, for fragment B, it isn't.
Things I've tried:
Using <requestFocus /> in fragment B
Requesting focus in code
Setting the importantForAccessibility state of the "Loading" fragment just before navigating away
If I change the loading fragment to use buttons for navigation, instead of the automatic behaviour, the focus does pass correctly, but obviously doesn't provide the right experience.
class LoadingFragment : Fragment() {
private lateinit var rootView: View
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_main, container, false).also {
rootView = it
}
private var beenHereBefore = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Mimic a delayed loading process
Handler(Looper.getMainLooper()).postDelayed({
// Navigate to the correct screen, based on state
findNavController().navigate(
if (beenHereBefore) {
R.id.action_mainFragment_to_fragmentB
} else {
beenHereBefore = true
R.id.action_mainFragment_to_fragmentA
}
)
}, 5000)
}
}
fragment_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:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.LoadingFragment">
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MainFragment"
android:textColor="#color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
class FragmentA : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_a, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button).setOnClickListener {
findNavController().popBackStack()
}
}
}
fragment_a.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">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment A"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="308dp"
android:text="Continue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
class FragmentB : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_b, container, false)
}
fragment_b.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">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment B"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
main_graph.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_graph"
app:startDestination="#id/mainFragment">
<fragment
android:id="#+id/mainFragment"
android:name="com.example.navigationtestapp.ui.main.LoadingFragment"
android:label="fragment_main"
tools:layout="#layout/fragment_main" >
<action
android:id="#+id/action_mainFragment_to_fragmentA"
app:destination="#id/fragmentA" />
<action
android:id="#+id/action_mainFragment_to_fragmentB"
app:destination="#id/fragmentB" />
</fragment>
<fragment
android:id="#+id/fragmentA"
android:name="com.example.navigationtestapp.ui.main.FragmentA"
android:label="FragmentA" />
<fragment
android:id="#+id/fragmentB"
android:name="com.example.navigationtestapp.ui.main.FragmentB"
android:label="FragmentB" />
</navigation>
If I were you will try to handle the accessibility focus using the accessibility API and not the requestFocus. You've mentioned that the the focus seems to be held by the loading screen, so this should work due that the a11y focus will follow it, but I will try to handle that using the sendAccessibilityEvent method
https://developer.android.com/reference/android/view/accessibility/AccessibilityEventSource#sendAccessibilityEvent(int)
// Moving a11y focus from btn1 to btn 2
btn1 = (Button) findViewById(R.id.screen3_btn1);
btn2 = (Button) findViewById(R.id.screen3_btn2);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btn2.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
});
Excellent answer about this: Android - Set TalkBack accessibility focus to a specific view
Hope this helps

Why is my merge layout showing up twice inside LinearLayout?

I have a merge layout inside a parent LinearLayout. For some reason, the merge layout is showing up twice, one on top of the other, in the fragment when I run my app. Layout Inspector shows all the elements from the merge layout repeated below the first set, and all directly under the LinearLayout. Even weirder is that the repeated elements have the same id's.
Parent layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/child_layout" />
</LinearLayout>
Child layout:
<merge
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="stuff" />
<Button
android:id="#+id/positiveButton"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="#+id/negativeButton"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</merge>
Fragment code:
private var _binding: ParentBinding? = null
private val binding get() = _binding!!
private var _contentBinding: ChildBinding? = null
private val contentBinding get() = _contentBinding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = ParentBinding.inflate(layoutInflater)
_contentBinding = ChildBinding.inflate(layoutInflater, binding.root)
return binding.root
}
What's Happening?
You are inflating the parent layout 2 times in onCreateView.
Solution
Replace this: _contentBinding = ChildBinding.inflate(layoutInflater, binding.root)
With this: _contentBinding = ChildBinding.bind(binding.root)

NavigationComponent recyclerview return shared element transition

I use Navigation Component in project. Trying to set up shared element transitions from recycler. And enter transition in the second fragment works fine, but when I return to the first fragment - there is no return transition.
I tried to explicitly set enter and return transitions in the first fragment like I did in the second like this
val transition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
sharedElementEnterTransition = transition
sharedElementReturnTransition = transition
but it didn't help.
Also tried to remove enter and exit fragment animations. For the second fragment enter transition works with animations, but who knows.
also tried to use the solution from this question, but in my case it didn't work.
https://stackoverflow.com/a/52922835/10951565
mainFragment
stickyAdapter.onItemClick = { event, imageView, textView ->
val args = bundleOf(EventDetailFragment.EVENT to event)
val extras = FragmentNavigatorExtras(
imageView to imageView.transitionName,
textView to textView.transitionName
)
findNavController().navigate(R.id.action_global_eventDetailFragment, args, null, extras)
}
in adapter onClick I set unique transition names for the views:
mainFragmentAdapter
eventImageView.setOnClickListener {
titleTextView.transitionName = "${event.title}$TRANSITION_TITLE"
eventImageView.transitionName = "${event.title}$TRANSITION_IMAGE"
onItemClick?.invoke(event, eventImageView, titleTextView)
}
in detailsFragment I get transition names from arguments (copypasted them to be sure there is no mistakes and for enter transition it worked)
I call postponeEnterTransition() in OnCreate method to wait until i can set transition names, sharedElementEnterTransition and sharedElementReturnTransition in onViewCreated and then call startPostponedEnterTransition()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
postponeEnterTransition()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_event_detail, container, false).apply {
val event = arguments?.getSerializable(EVENT) as Event?
toolbarImageView.transitionName = "${event?.title}$TRANSITION_IMAGE"
titleTextView.transitionName = "${event?.title}$TRANSITION_TITLE"
val transition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
sharedElementEnterTransition = transition
sharedElementReturnTransition = transition
startPostponedEnterTransition()
toolbar.setupWithNavController(findNavController())
event?.let {
Picasso.get()
.load("${EventGroupAdapter.BASE_SMALL_IMAGE_URL}${event.smallimage}")
.into(toolbarImageView)
}
}
}
main_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".view.activity.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="256dp"
android:background="?android:colorBackground"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:fitsSystemWindows="true" />
<com.rd.PageIndicatorView
android:id="#+id/pageIndicatorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/viewPager"
android:layout_centerHorizontal="true"
android:layout_marginBottom="7dp"
app:piv_dynamicCount="true"
app:piv_interactiveAnimation="true"
app:piv_radius="3.5dp"
app:piv_selectedColor="#color/colorIndicatorSelected"
app:piv_unselectedColor="#color/colorIndicatorUnselected"
app:piv_viewPager="#id/viewPager" />
<include
android:id="#+id/horizontalScrollView"
layout="#layout/fragment_main_horizontal_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/viewPager" />
</RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="#+id/emptyMessage"
android:layout_marginTop="40dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layoutAnimation="#anim/layout_animation_from_bottom"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/ic_empty_events"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/empty_events_message"
android:textSize="18sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="48dp"
android:nestedScrollingEnabled="true"
tools:listitem="#layout/fragment_main_event_item" />
</RelativeLayout>
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/programTextView"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:colorBackground"
app:menu="#menu/bottom_navigation" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Please share your recipe of the return shared element transition with Navigation Component
I ran into this the other day where going from the MainFragment item to a DetailFragment animated fine, but the sharedElementReturnTransition wasn't working when pressing back.
The fix for me was to postpone the transition on the MainFragment. At first, I was trying to do so in onCreate, but onCreate isn't always called when going back, so the fix was to postpone it in onViewCreated (I would guess onCreateView might work too) and then start the transition once the RecyclerView is ready.
DetailFragment:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val transition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
sharedElementEnterTransition = transition
sharedElementReturnTransition = transition
}
MainFragment:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
postponeEnterTransition()
recycler_view.post { startPostponedEnterTransition() }
}

Android Navigation Component Not Displaying Fragment

I'm trying to implement the new Android Navigation Component in an existing app.
I have 2 fragments that are identical except for their name. When I set the startDestination to fragment2, the fragment seems to be shown correctly. When the startDestination is set to fragment1, I don't see the inflated view but I do see the "Fragment 1 created" toast.
What am I doing incorrectly?
class Fragment1 : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
Toast.makeText(context, "Fragment 1 created", Toast.LENGTH_LONG).show()
return inflater.inflate(R.layout.fragment1, container, false)
}
}
class Fragment2 : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
Toast.makeText(context, "Fragment 2 created", Toast.LENGTH_LONG).show()
return inflater.inflate(R.layout.fragment2, container, false)
}
}
nav_graph.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/nav_graph"
app:startDestination="#id/fragment1">
<fragment
android:id="#+id/fragment1"
android:name="com.package.anotherpackage.ui.Fragment1"
android:label="fragment1"
tools:layout="#layout/fragment1"/>
<fragment
android:id="#+id/fragment2"
android:name="com.package.anotherpackage.ui.Fragment2"
android:label="fragment2"
tools:layout="#layout/fragment2"/>
</navigation>
MainActivity layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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:background="#android:color/background_light"
tools:context=".MainActivity">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/nav_graph"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</FrameLayout>
Fragment1 Layout:
<?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"
tools:context=".ui.Fragment1"
>
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="fragment 1"
/>
</FrameLayout>
Dependencies:
//Navigation
def nav_version = "1.0.0-alpha05"
implementation "android.arch.navigation:navigation-fragment-ktx:$nav_version"
implementation "android.arch.navigation:navigation-ui-ktx:$nav_version"
// optional - Test helpers
androidTestImplementation "android.arch.navigation:navigation-testing-ktx:$nav_version"
I had a layout in another library in my project with the name "fragment1.xml".
It must have been conflicting with the other layout I was trying to inflate in Fragment1. Renaming the Fragment1 layout fixed the issue.

Categories

Resources