dotnet / android-libraries

.NET for Android bindings for Google's libraries, such as AndroidX, GooglePlayServices, Firebase, and MLKit and their 3rd party dependency libraries.
MIT License
230 stars 48 forks source link

Why can't my project recognize Navigation resources? #410

Closed petro2050 closed 1 year ago

petro2050 commented 3 years ago

I'm trying to set a navigation graph either declaratively or programmatically, but Xamarin can't find the xml file.

Programmatically:

var navHostFragment = SupportFragmentManager.FindFragmentById(Resource.Id.nav_host_container) as NavHostFragment;
navController = navHostFragment.NavController;
var inflater = navController.NavInflater;
var graph = inflater.Inflate(Resource.Navigation.nav_graph);
navController.SetGraph(graph);

s1

Declaratively:

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_container"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

s2

I deleted bin and debug folders and tried rebuilding with no luck. I'm using min sdk 26 and target sdk 30.

gmck commented 3 years ago

@petro2050

You need Xamarin.AndroidX.Navigation to get the Navigation class and then you can do

navController = Navigation.FindNavController(this, Resource.Id.nav_host);

I'm not sure about FragmentContainerView. When I first did it it was not supported, but that was a long time ago. I'm just using fragment for the nav_host in my content_main.xml. I've not tried since this works fine.

for example

<fragment
            android:id="@+id/nav_host"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toTopOf="@+id/main_bottom_navigation_view"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/nav_graph" />
petro2050 commented 3 years ago

@gmck

For me, the issue is not finding the nav controller. In fact, I could get it like this:

var navHostFragment = SupportFragmentManager.FindFragmentById(Resource.Id.nav_host_container) as NavHostFragment;
navController = navHostFragment.NavController;

However, I'm unable to inflate a nav graph because Resource.Navigation does not exist. See the first image attachment in the original post.

Also, I tried using fragment instead of FragmentContainerView. Same result. Do you have an MVP with a working nav graph example? Not sure if my project is misconfigured.

gmck commented 3 years ago

@petro2050

You could look at https://github.com/gmck/NavigationCodeLab to check whether you have misconfigured your project. It was uploaded Aug 2020, so it would need updating re the AndroidX libs. You do have a navigation folder under Resources??

petro2050 commented 3 years ago

Yes. I have a navigation folder under Resources.

gmck commented 3 years ago

What do you have in Resource.Designer.cs for public partial class Navigation? What version of Visual Studio?

petro2050 commented 3 years ago

VS 2019 (version 16.11.2)

When I rebuild the solution, I'm getting a compile-time error:

error

Here's the project itself:

App4.zip

gmck commented 3 years ago

When I try and build your app4 I get the same errors as you. If you search your Resource.Designer.cs you don't find the Class Navigation which explains your red sqigglies.

I've never seen the approach you have taken with the nav_graph where you have basically a blank graph and then all the etcs. as separate xmls. My graph just includes all the fragments as separate onr for each. I presume this is some newer technique that I'm not aware off. Can you give me a link to where you came across this technique? I'd like to try and reproduce it but without modifying what you have done.

Assumming that technique is meant to work, I then see you have namespace problems inside each of those separate xml files. They all refer to com.companyname.App4, but your default namespace is just app4.

For example

<fragment
        android:id="@+id/titleScreen"
        android:name="com.companyname.app4.home.Title"
        android:label="Home"
        tools:layout="@layout/fragment_title">
        <action
            android:id="@+id/action_title_to_about"
            app:destination="@id/aboutScreen"/>
    </fragment>

The android:name of each must match the fully qualified class name of your Fragment. For that matter you don't even have any Fragment classes in your solution. So the first step is to create those Fragments (don't use Title in the name though) using a matching namespace. I would suggest that you change the default namespace of the project to com.companyname.App4. Create a new folder called Fragments and add each fragment there. All they need for starters are a public parameterless contructor, plus an OnCreateView which just has return inflater.Inflate(Resource.Layout.fragment_, container, false); In my case they are all in my Resources.Layout folder.

Even though the NavController navigates by the Fragment android.Id or matching menuitemId, the Android runtime still needs to able to instantiate the fragment via its ctor, for instance on a configuration change. Therefore it needs a matching fully qualified class name.

If you take a look at link I sent you can base a new project on that using your data.

Conversely if you send me the Android link you started with I will play around with this new technique and potentially add another more modern example to github.

petro2050 commented 3 years ago

Thanks for taking a look. I was trying to base the new approach off of https://github.com/android/architecture-components-samples/tree/master/NavigationAdvancedSample.

This is the file that nests multiple graphs: https://github.com/android/architecture-components-samples/blob/master/NavigationAdvancedSample/app/src/main/res/navigation/nav_graph.xml

Also, take a look at this article: https://medium.com/androiddevelopers/navigation-multiple-back-stacks-6c67ba41952f

So, I'm trying to create multiple back stacks and switch between them via BottomNavigationView.

It'd be great if you can add a more modern Xamarin example!

gmck commented 3 years ago

@petro2050

Thanks for the links. I've had a quick look at the sample and read Ian Lakes article. I then remembered that I had read it before. At that time, I didn't think it would help in my situation and I wasn't prepared to change my app just to suit their version of multiple back stacks as I already had a complex setup that was working fine. I make extensive use of OnBackPressedCallback for most of my fragments and like the control, it gives me, in that I can pop and where I want to specifically when leaving each fragment. It also gives you the flexibility of optionally creating your own NavOptions to control how different fragments perform. My Navigation is complicated in that it uses Navigation Drawer mainly, but a couple of Fragments also use BottomNavigationView, and then you have an additional 3 dot menu for all the maintenance type fragment items, being able to control all that exactly without being concerned about the default behaviour seems more important to me.

I will do the same as with the original NavigationCodeLab and add a new example based on their NavigationAdvancedSample. Can't promise when, but I will get to it.

I presume you now know how to get your sample app working. If not just continue.

petro2050 commented 3 years ago

Thank you! I will wait for any updates on your side.

gmck commented 3 years ago

@petro2050 I've got that NavigationAdvancedSample working. However, I'm not all that interested in spending more time publishing it because other than showing support for multi back stacks it really doesn't do much.

If you would like me to send it to you can you please contact me by email?

petro2050 commented 3 years ago

@gmck emailed you.

petro2050 commented 2 years ago

@gmck

In your sample attached on https://github.com/xamarin/xamarin-android/issues/6425, when I tap "About" on the Home tab and then tap "Register" and tap Home again, the navigation stack for the first tab is cleared.

Would you mind telling me how to retain the current page for each tab as the user tabs through the bottom navigation bar?

gmck commented 2 years ago

Hi,

I’m not sure what you mean, but I guess what you are saying re the Register fragment is that the name, email etc are not retained when you navigate to a different fragment and then back to the register fragment.

However, there was never any mechanism in the original android sample that could have provided that functionality.

I think I said that I thought it was a pretty useless sample, which was why I lost interest in it after getting it working in C#, more or less, for you.

I think what you are looking for are examples of using ViewModels and LiveData, which from memory those samples at https://github.com/android/architecture-components-samples did have.

Regards

Graham

From: petro2050 @.> Sent: Thursday, 24 March 2022 2:18 PM To: xamarin/AndroidX @.> Cc: Graham McKechnie @.>; Mention @.> Subject: Re: [xamarin/AndroidX] Why can't my project recognize Navigation resources? (#410)

@gmck https://github.com/gmck

In your sample attached on xamarin/xamarin-android#6425 https://github.com/xamarin/xamarin-android/issues/6425 , when I tap "About" on the Home tab and then tap "Register" and tap Home again, the navigation stack for the first tab is cleared.

Would you mind telling me how to retain the current page for each tab as the user tabs through the bottom navigation bar?

— Reply to this email directly, view it on GitHub https://github.com/xamarin/AndroidX/issues/410#issuecomment-1077026089 , or unsubscribe https://github.com/notifications/unsubscribe-auth/ABRB2O7NDQ75GHFOZEHBML3VBPNGLANCNFSM5FYZ3DRA . You are receiving this because you were mentioned. https://github.com/notifications/beacon/ABRB2O25KIGREHXRLD237RTVBPNGLA5CNFSM5FYZ3DRKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOIAZB2KI.gif Message ID: @. @.> >

moljac commented 1 year ago

Closing this issue