NavHostFragment app:navGraph requires 'String' resource instead of 'Navigation' resource - android

I'm using Android Studio 3.4.2 and trying to implement some basic navigation features in my app.
I am following the official documentation to setup a NavHostFragement (via a FragmentContainerView) and linking the appropriate graph to it. However, when I do this, I get an error on the app:navGraph attribute stating:
Unexpected resource type: 'navigation' expected: string.
This causes the app to crash on start-up and the nav_graph itself gives a warning that it's not linked to a host.
Main 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">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:navGraph="#navigation/nav_graph" />
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="358dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:layout_marginBottom="696dp"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
nav_graph.xml (It already contains a couple off fragments and actions):
<?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/home_screen">
<fragment
android:id="#+id/home_screen"
android:name="com.example.ordersysteem2.home_screen"
android:label="home_screen" >
<action
android:id="#+id/action_home_screen_to_prepare"
app:destination="#id/prepare" />
<action
android:id="#+id/action_home_screen_to_kalkoenSalami"
app:destination="#id/kalkoenSalami" />
</fragment>
<fragment
android:id="#+id/prepare"
android:name="com.example.ordersysteem2.prepare"
android:label="fragment_prepare"
tools:layout="#layout/fragment_prepare" />
<fragment
android:id="#+id/kalkoenSalami"
android:name="com.example.ordersysteem2.kalkoenSalami"
android:label="fragment_kalkoen_salami"
tools:layout="#layout/fragment_kalkoen_salami" />
</navigation>

Related

back button does not work well when using search view

I'm new in android and I have a search view in a fragment that when its text changes the results appear in a recycler view. The problem is when back button is pressed, only the query text is removed and it does not go to the previous fragment. What shall I do to make the back button work as it should.
<?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"
android:layout_margin="8dp">
<androidx.appcompat.widget.SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="16dp"
android:layoutDirection="rtl"
app:iconifiedByDefault="false"
app:layout_constraintTop_toTopOf="parent"
app:searchIcon="#drawable/ic_baseline_search_24" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layoutDirection="rtl"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintTop_toBottomOf="#id/searchView" />
</androidx.constraintlayout.widget.ConstraintLayout>
.
<?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"
android:id="#+id/shopping_nav"
app:startDestination="#id/homeFragment">
<fragment
android:id="#+id/homeFragment"
android:name="com.example.shopingofmine.ui.home.HomeFragment"
android:label="Home" >
>
<action
android:id="#+id/action_homeFragment_to_searchFragment"
app:destination="#id/searchFragment"
/>
</fragment>
<fragment
android:id="#+id/searchFragment"
android:name="com.example.shopingofmine.ui.search.SearchFragment"
android:label="SearchFragment" >
</fragment>
</navigation>

Configurations for activity_main.xml must agree on the root element's ID. Missing ID: - layout #+id/drawer_layout: - layout-land

Im using viewbinding, and i get this error when i build
Configurations for activity_main.xml must agree on the root element's ID.
Missing ID:
- layout
#+id/drawer_layout:
- layout-land
It says i need to have two different id for rootview. But i have different root for portrait layout and landscape layout. Like below. If i put same id to drawerlayout(landscape) and same id for constraintlayout(portrait) it creates problem in code. That to i wrote common code without checking orientation.
How to get rid of this error, using <include id> or <merge> or anyother ways?
(i dont know how these works exactly for my needs) without checking orientations in code blocks.
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/purple_500"
android:theme="#style/Widget.AppCompat.Toolbar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<fragment
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/mobile_navigation"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottom_nav"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/nav_host_fragment"
app:layout_constraintVertical_bias="1.0"
app:menu="#menu/menu_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
land/activity_main.xml
<?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"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:theme="#style/ToolbarTheme" />
<fragment
android:id="#+id/nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/mobile_navigation"
app:defaultNavHost="true" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/menu_navigation" />
</androidx.drawerlayout.widget.DrawerLayout>
code
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
You're using a </androidx.constraintlayout.widget.ConstraintLayout> for the portrait and a </androidx.drawerlayout.widget.DrawerLayout> for the landscape orientation. Hence the error.. You can try running the app after wrapping the drawer layout in a constraint layout and giving each an identical id

Android jetpack navigation producing an unexpected error

I am trying to use the new navigation graph in android for swapping between fragments. However, I get an error saying :
This navigation graph is not referenced from any layout files (expected to find it in at least one layout file with a NavHostFragment with app:navGraph="#navigation/nav_graph" attribute). Navigation resource files must be referenced from a NavHostFragment in a layout in order to be relevant.
I have seen many poeple with the same error, but everyone seemed to have done something wrong and could correct it. In my case, I am almost 100% sure my code is ok...
Here is my nav_graph.xml :
<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/mainFragment">
<fragment
android:id="#+id/mainFragment"
android:name="com.ouimet.budget.MainFragment"
android:label="fragment_main"
tools:layout="#layout/fragment_main" >
<action
android:id="#+id/action_mainFragment_to_expenseFragment"
app:destination="#id/expenseFragment" />
</fragment>
<fragment
android:id="#+id/expenseFragment"
android:name="com.ouimet.budget.ExpenseFragment"
android:label="fragment_expense"
tools:layout="#layout/fragment_expense" />
</navigation>
Along with my MainActivity's resource file activity_main.xml (which references the nav_graph.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=".MainActivity">
<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:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
And my 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainFragment"
android:id="#+id/parentLayout">
<Button
android:id="#+id/view_expense_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Entrer une dépense"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
As we can see, my nav_graph is referenced.. Also, when I compile and run the code, the transition between the fragments works! Is this a known issue or just me not seeing something?
Thank you for your help!
Alexandre

How to navigate back to the master screen from the details with Nav controller on Android

I have the following 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"
app:startDestination="#id/users_fragment"
android:id="#+id/nav_graph">
<fragment
android:id="#+id/users_fragment"
android:name="com.package.UsersFragment"
tools:layout="#layout/users_fragment"
android:label="UsersFragment">
<action
android:id="#+id/action_users_fragment_to_profile_fragment"
app:destination="#id/profile_fragment"
app:popUpTo="#id/users_fragment"
app:popUpToInclusive="true"/>
</fragment>
<fragment
android:id="#+id/profile_fragment"
android:name="com.package.ProfileFragment"
android:label="ProfileFragment">
<argument
android:name="userId"
app:argType="string" />
</fragment>
</navigation>
The main activity xml is:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.package.UsersViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:background="#color/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/app_bar_layout"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
To navigate to the details I call:
val action = UsersFragmentDirections
.actionUsersFragmentToProfileFragment(
userId = user.userId,
)
navController.navigate(action)
where UsersFragmentDirections is generated by the safe-args plugin.
The problem is that when I press back the master fragment is not shown: the activity is closed.
If in the action I use app:popUpToInclusive="false" then the back button does not work anymore.
What should I do to be able to go to the UsersFragment from the ProfileFragment when the user press back?
You're popping users fragment while moving to profile fragment. So when you press back, there is nothing in the backstack and hence activity finishes..
So, to fix this issue you have two options:
1) Manually re-open/navigate users fragment
Or
2) Remove these two lines
app:popUpTo="#id/users_fragment"
app:popUpToInclusive="true"

Navigation destination is unknown to this NavController

When I clicked on the button this thing is happening
navigation destination com.android.example.cameraxbasic:id/action_camera_to_gallery is unknown to this NavController
This is my code in fragment
container.findViewById<ImageButton>(R.id.photo_view_button).setOnClickListener {
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(
CameraFragmentDirections.actionCameraToGallery(outputDirectory.absolutePath))
}
This is a full error description
In my case , I am using HomeFragment Having FragmentOne and FragmentTwo in HomeFragment
<?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=".HomeFragment">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="729dp"
android:fillViewport="true"
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
android:layout_width="match_parent"
android:layout_height="match_parent" >
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentOne"
android:name="com.example.FragmentOne"
android:layout_width="match_parent"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentTwo"
android:name="com.example.FragmentTwo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fragmentCarosuel" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
my nav_main.xml file is like below:
<?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/mobile_navigation"
app:startDestination="#+id/nav_home">
<fragment
android:id="#+id/nav_home"
android:name="com.example.HomeFragment"
android:label="#string/menu_home"
tools:layout="#layout/fragment_home">
<action
android:id="#+id/action_main_to_fragment_three"
app:destination="#id/fragmentThree" />
</fragment>
<fragment
android:id="#+id/fragmentThree"
android:name="com.example.FragmentThree"
android:label="fragment_three"
tools:layout="#layout/fragment_three" >
</fragment>
</navigation>
Now, I am Navigating from FragmentTwo any click event etc.:
NOTE: Please make sure while selection of navigation destingation in navGraph. Here i am using two sub fragment (FragmentOne and FragmentTwo) but my base fragment is HomeFragment. so i have to make action from HomeFragment. If anyone create destination from FragmentOne it is not accesible from HomeFragment and NavController did not identify.
HomeFragmentDirections.ActionMainToFragmentThree nextAction = HomeFragmentDirections.actionMainToFragmentThree();
NavController navController = NavHostFragment.findNavController(this);
navController.navigate(nextAction);
Sorry for poor English. Thanks

Categories

Resources