I'm using a navigation graph to navigate from fragment A to B with animation slide up duration =0.4s, but while 0.4s before fragment B appears, fragment A becomes a white screen, not keep state data and UI before.
Update:
I tried to clone a sample project with some background color config at all screen. And I found that when navigating to fragment B, fragment A is removed and replaced by fragment B, so the main activity layout contains fragment is visible with the background color of it during 0.4s.
activity_main.xml
<?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:background="#F1E78C"
tools:context="com.myricseptember.countryfact.ui.MainActivity">
<fragment
android:id="#+id/navigationHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/countryfact_navigation_graph"/>
</android.support.constraint.ConstraintLayout>
fragment_country_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="#123456">
<android.support.v7.widget.RecyclerView
android:id="#+id/countryRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="#layout/layout_list_item" />
</RelativeLayout>
fragment_country_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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="#CAEACB">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.constraint.ConstraintLayout>
</ScrollView>
countryfact_navigation_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/countryfact_navigation_graph"
app:startDestination="#id/countryListFragment">
<fragment
android:id="#+id/countryListFragment"
android:name="com.myricseptember.countryfact.ui.list.CountryListFragment"
android:label="Country Fact"
tools:layout="#layout/fragment_country_list">
<action
android:id="#+id/action_countryListFragment_to_countryDetailsFragment"
app:destination="#id/countryDetailsFragment"
app:enterAnim="#anim/slide_up"
app:popExitAnim="#anim/slide_down" />
</fragment>
<fragment
android:id="#+id/countryDetailsFragment"
android:name="com.myricseptember.countryfact.ui.details.CountryDetailsFragment"
android:label="CountryDetailsFragment"
tools:layout="#layout/fragment_country_details" />
/>
</navigation>
And video record of issues:
=> How to custom navigation add fragment (not remove-replace) or custom handle remove A after fragment B transaction up?
Related
I'm running into a wall debugging what should be a simple issue: I have an app with one activity, which contains a navigation graph, which should display a fragment on start. But it isn't.
activity_main.xml
<?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"
tools:context=".MainActivity"
>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph"/>
</FrameLayout>
res/navigation/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/listFragment"
>
<fragment
android:id="#+id/listFragment"
android:name="org.example.my_app.ui.ListFragment"
android:label="fragment_list"
tools:layout="#layout/fragment_list"
>
<action
android:id="#+id/action_listFragment_to_detailFragment"
app:destination="#id/detailFragment"
/>
</fragment>
<fragment
android:id="#+id/detailFragment"
android:name="org.example.my_app.ui.DetailFragment"
android:label="fragment_detail"
tools:layout="#layout/fragment_detail"
/>
</navigation>
fragment_list.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"
tools:context=".ui.ListFragment"
>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="This should be visible"
/>
</FrameLayout>
ListFragment.kt
class ListFragment : Fragment(R.layout.fragment_list)
Despite this dead-simple setup, I see a blank screen (just an app bar) and debug listeners added to the ListFragment class init don't ever get called. Why isn't my navGraph initializing an instance of the fragment?
Documentation:
NavHostFragment provides an area within your layout for self-contained navigation to occur.
You are missing to declare the fragment placeholder as a NavHostFragment in the FragmentContainerView via the android:name attribute; and therefore the navigation won't occur.
<androidx.fragment.app.FragmentContainerView
....
android:name="androidx.navigation.fragment.NavHostFragment"
NavgationHostFragment is not working.
//activity_main
<?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/fragment3"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_main"
tools:layout_editor_absoluteX="131dp"
tools:layout_editor_absoluteY="201dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
//nav_main
<?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_main"
app:startDestination="#id/welcomeFragment2">
<fragment
android:id="#+id/welcomeFragment2"
android:name="com.example.fragmenttest.WelcomeFragment"
android:label="WelcomeFragment" />
</navigation>
I don't know why.
The process is not described in the Fragment or other documents.
Please give me a hint how to make the Fragment xml show up instead of Activity_main.
I have been struggling with this for several days.
Thank you for your help.
I'm sorry, I didn't add theAdapter and it's not showing up.
I have followed a guide on creating android navigation with the androidx navigation package. However, I am having troubles displaying anything. When the app starts it shows and empty activity and not the content of my fragment.
Do you have to do anything extra in order to let it show the start screen of the navigation graph?
Launcher xml
<?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_height="match_parent"
android:layout_width="match_parent">
<fragment
android:id="#+id/launcherNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="#navigation/navigation_launcher" />
</FrameLayout>
Navigation graph (navigation_launcher)
<?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/navigation_launcher"
app:startDestination="#id/launcherFragment">
<fragment
android:id="#+id/launcherFragment"
android:name="com.myapp.Views.LauncherFragment"
android:label="fragment_launcher"
tools:layout="#layout/fragment_launcher" >
<action
android:id="#+id/action_launcherFragment_to_mainActivity"
app:destination="#id/mainActivity" />
</fragment>
<activity
android:id="#+id/mainActivity"
android:name="com.myapp.Views.MainActivity"
android:label="activity_main"
tools:layout="#layout/activity_main" />
</navigation>
The fragments are just basic fragments with a text view inside. Nothing special here.
Any ideas on what is missing?
As far as I see from the code you posted there are some errors in your configuration:
The nav host fragment should be contained in activity_main.xml (or your main activity layout file, the main activity should be defined in your manifest file and it's the one responsible to load the first fragment displayed by the app
The launcher fragment layout should not contain a NavHostFragment itself, but it should have some views inside the frame layout (a textview displaying some text for example)
- activity_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/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/navigation_launcher" />
</androidx.constraintlayout.widget.ConstraintLayout>
- fragment_launcher.xml
<?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_height="match_parent"
android:layout_width="match_parent">
<TextView android:text="I'm the launcher fragment"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</FrameLayout>
My app has two activities. One is the login activity and this is the activity that is shown when the user starts the app. After successfully signing in, I want to navigate to the main activity.
I have not been able to successfully do this using the navigation editor.
Here is the layout for my login activity:
<fragment
android:id="#+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:navGraph="#navigation/nav_graph_login"
app:defaultNavHost="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
tools:layout_editor_absoluteY="450dp"
tools:layout_editor_absoluteX="201dp">
</fragment>
This is the navigation graph for the login activity:
<?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_login"
/>
This is the layout of my main activity:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<fragment
android:id="#+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:navGraph="#navigation/nav_graph_main"
app:defaultNavHost="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
tools:layout_editor_absoluteY="450dp"
tools:layout_editor_absoluteX="201dp"/>
</androidx.drawerlayout.widget.DrawerLayout>
And the navigation graph for the main activity:
<?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_main"
app:startDestination="#id/loginActivity">
</navigation>
I see nothing in the navigation editor where I can connect the login activity to the main activity.
The navigation editor is to allow you to navigate to different Fragments within one Activity. Each activity will have it's own navigation component (as you have done). Launching your MainActivity from your login activity, and activity life-cycle, needs to be handled outside of this.
While designing the main activity I tried to add two fragments.But the original structure of the fragment is not shown in design tab of activity_main, instead shaded regions are shown for each fragment.How to get original structure of fragments during design?
enter image description here
In your activity_main.xml make sure each of your fragment tags specify:
android:name with a path to your fragment
tools:layout with the fragment's layout
If you're using an include tag then you'll need to use something like tools:showIn=".MainActivity" (docs) in your fragments.
Here's an example:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<fragment android:name="com.example.FirstFragment"
android:id="#+id/firstFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout="#layout/fragment_first" />
<fragment android:name="com.example.SecondFragment"
android:id="#+id/secondFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout="#layout/fragment_second" />
</LinearLayout>
fragment_first.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"
tools:context=".FirstFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>