Home > Software engineering >  navigate to BottomSheetDialogFragment using jetpack navigation
navigate to BottomSheetDialogFragment using jetpack navigation

Time:12-23

Im trying to use jetpack navigation to navigate from a Fragment to a BottomSheetDialogFragment but every time I try to navigate it just crash the app saying it cannot find the class name.

mobile_navigation.xml

<fragment
  android:id="@ id/home_dest"
  android:name="TestProject.Fragment.HomeFragment">
    <action
            android:id="@ id/action_home_to_bottom_sheet"
            app:destination="@id/bottom_dialog"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" /></fragment>

<dialog
  android:id="@ id/bottom_dialog"
  android:name="TestProject.Dialog.BottomDialog" />

BottomDialog.cs

namespace TestProject.Dialog
{
    public class BottomDialog : BottomSheetDialogFragment
    {
        public override View? OnCreateView(LayoutInflater inflater, ViewGroup? container, Bundle? savedInstanceState)
        {
            base.OnCreateView(inflater, container, savedInstanceState);
            return inflater.Inflate(Resource.Layout.bottom_sheet_layout, container, false);
        }
    }
}

HomeFragment.cs button click navigation

private void OnButtonClick(object sender, EventArgs e)
{
    var nav = Navigation.FindNavController(Activity, Resource.Id.my_nav_host_fragment);
    nav.Navigate(Resource.Id.action_home_to_bottom_sheet);
}

Error

AndroidX.Fragment.App.Fragment InstantiationException: Unable to instantiate fragment TestProject.Dialog.BottomDialog: make sure class name exists ---> Java.Lang.ClassNotFoundException: TestProject.Dialog.BottomDialog ---> Java.Lang.ClassNotFoundException: Didn't find class "TestProject.Dialog.BottomDialog" on path: DexPathList[[zip file "/data/app/~~aFH8kN7HhPmbIpV2HNo5Pw==/"package_name"-iUb68ulDoLpefgk2DFn_XQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~aFH8kN7HhPmbIpV2HNo5Pw==/package_name-iUb68ulDoLpefgk2DFn_XQ==/lib/arm64, /data/app/~~aFH8kN7HhPmbIpV2HNo5Pw==/package_name-iUb68ulDoLpefgk2DFn_XQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]] 12-21 23:38:50.355 E/AppCenterXamarinCrashes(21237): --- End of inner exception stack trace --- 12-21 23:38:50.355 E/AppCenterXamarinCrashes(21237): --- End of inner exception stack trace ---

With all of this, I get a crash saying it can't find the class named BottomDialog which is impossible because if I change on the mobile_navigation the tag from <dialog to <fragment it can indeed navigate but lose all the behavior that a bottom Sheet must have. I dont know if im missing something or if it's just something regarding xamarin that does not work.

Does anyone knows what might be causing this and why? im out of ideas

Already tried to clean/rebuild, and reinstall nuggets, and still no good.

CodePudding user response:

@doczic,

At first glance, I don't see anything wrong. The usual reason for the Java.Lang.ClassNotFoundException is a typo in your nav_graph - (I've had a heap of them) not matching the fully qualified fragment class name. I only use Fragments in my nav_graphs as I don't like the extra stuff, like animations and actions etc. I prefer to do animations via NavOptions, which allows you to have more than one sort of animation etc and allows a lot of flexibility. I found too many things I didn't like about graphs and so now I restrict it to just the fragments and then write extra code to Navigate.

I use BottomDialogs as HelperDialogs in many places in my production apps to explain not-so-obvious features and allow the user to optionally turn them off once they know the app.

I've got a bunch of tutorials on the NavigationComponent called NavigationGraph(x) where x equals a number, which demonstrates how I evolved from the standard stuff to do more stuff via code as the number increments.

It may not fix your particular problem, but it does demonstrate how to use a BottomSheetDialogFragment. NavigationGraph7 is the project where I first introduced BottomDialogs. There is also a Navigation7Net7 project but that is the same project converted to a Net7 project, whereas the NavigationGraph7 is xamarin.android classic.

CodePudding user response:

@doczic

its something kinda simple and it does not work no matter what I do, hence why Im starting to believe it might be something related with Xamarin

I wouldn’t get hung up on something like the dialog not working, as in the long run, I doubt you’ll end up wanting that functionality in the nav_graph anyway. However, I doubt that particular problem has anything to do with Xamarin.

Google had a very good idea when it came up with the NavigationComponent, but maybe they took the nav_graph concept just a little too far. The major idea was to get away from multiple activities and fragment transactions. Fragment transactions being the most difficult thing to work with. Step back a bit and think of the overall structure of any Android app and consider the 3 important layouts that every android app is likely to use. activity_main, app_bar_main and content_main. The most important one is content_main. It contains the FragmentContainerView which holds the NavHostFragment. Every single fragment in your app fits in that FragmentContainerView, no matter how big your app grows. That enabled them not so much to do away with FragmentTransactions, but to hide the complexity of fragment transactions. You won’t find a single fragment transaction in any of those NavigationGraph projects.

The nav_graph should in my opinion just hold the fragments in other words a placeholder. You can even use it as a prototype tool – have a list of fragments that don’t even exist in code yet. That has no ill effect on building a project. So, if say you are converting an old project you can spec it out in the nav_graph of the new project. Where they went off the rails a touch was including stuff like bundles, animations, actions and info about how the back stack should pop etc in the nav_graph. Someone on their team must have also come up with NavOptions class because it is that class that gives us developers the ability to manually do what we want to do without having to pollute the nav_graph with all that extra stuff.

If you check out the NavigationGraph projects, you will see that I started off doing it their way (there is even a Xamarin converted NavigationCodeLab in there) and then as the projects increment I swapped away from their approach. I really doubt you are going to miss one particular dialog in a nav_graph when you can use something like the BasicDialogFragment which inherits from AppCompatDialogFragment allowing flexibility anywhere.

I've successfully converted two of my production apps and can say that they are far better and more reliable than the originals.

Just a note – some of the NavigationGraph projects have already been converted to Net7 projects, so you may want to concentrate on the ones without the net7 suffix to start with.

There are also problems with AndroidX.Navigation.Fragment and Navigation.Ui, that relate to their dependencies that become apparent as you increment both that need to be sorted out at Xamarin.Android. So don't automatically update those packages to the latest versions, use the versions noted in each project. Later projects may use updated versions though when stuff got fixed. However, nothing really that can't be worked around.

Forgot to mention where they are https://github.com/gmck

  • Related