How to use navigation component with a parent fragment? - android

I have an app, which is a single-activity app. I use dagger2 for di, and an abstraction for navigation.
Let's see a navigation flow: auth - select-info (A, B) - menu. As you can see, there are three main destinations, and the second one contains two screens. I want to make "select-info" as a parent fragment for A and B, but the way navigation component works, I cannot implement that behavior.
I tried to google it, but something close to this issue is an approach to use fragmenManager to go to parentFragment and internally use navComponent, but this approach does not work in my case, because somehow I need to change a navGraph.
As an alternative I see using viewPager in "select-info".

Related

How to reorganize messy android navigation graph?

So I use a single nav_graph.xml for the whole app. As the app grow it become messy jumble like shown below, and now it become so laggy to move around.
Is there any trick to untangle this thing without changing the code too much?
I also had this situation and it is normal , but you should refactor as it gets harder to make changes to that navigation graph or better understand your use cases and do it in the first place. Anyway the solution to that is you make a nested navigation graph for every feature of the app (if possible) , for example for profile option make a profile nested navigation graph now all fragment related to profile will go under that navigation graph and the navigation graph will become more manageable another advantage is that you can scope a viewmodel to the nested navigation graph, that means you can share data related to profile via that viewmodel.
As your navigation graph above how can you share data between those fragment , first you can use arguments but those are for limited data types , second you can have a viewmodel which is scoped to your single activity and and all your fragment share that data but that is also a really messy solution and huge impact on memory usage, since all memory used by activity viewmodel will remain consumed as long as the app is running.
So go will nested navigation graph, or if you want to have more activities you can also do that in that case other activities have their own navigation graphs.

How to use navigation architecture component to navigate dynamically

I have a use case and couldn't find an example of it online. So, my use case is I have a few fragments and the flow is decided by the server.Server returns a list of strings and based on the String, I have to navigate to a fragment. Eg:
Server returns ["detail_entry","accept_work","qr_code"] and depending on that I have to navigate using the navigation architecture component to DetailEntryFragment,AcceptWorkFragment or QRCodeScanningFragment. How to create Navigationaction directly in Kotlin code rather than use the navigation graph actions in xml.
I do not want to create an action between each and every fragment in xml and use it.I also want to mandate arguments passing. Is there any other way other of how to achieve this with the navigation architecture. I do not want to move to the old fragmentmanger and committing with them.

Navigation drawer with fragments or activities?

I know it was answered before but I am still confused, if I should use fragments or activities for navigation drawer.
What is better practice? Google does not say anything about it and I am a little dissapointed.
Also, if I create a new project from Android studio with navigation drawer template, what I get is one single activity and one single fragment, but there is also separate fragment for navigation drawer and inside it, there is an interface and above it is a comment saying: "Callbacks interface that all activities using this fragment must implement.". It confuses me even more because I think I should use activities, but I am not sure.
I will keep it very simple: When you switch between activities , user has a bit of feeling as if we are taking him to another view(as if we are making him switch somewhere and the whole view is changed with a sudden blink) but when you do same stuff in one activity and changing views through fragment, it is very smooth. Moreover passing data from one fragment to other is very easy and less expensive as android says activity transactions are expensive.
Yet many times it depends on your requirement.
Keep in mind that a nav-drawer can be used for different user interactions. By the common usage as a navigation element, you will implement it by fragment(s). In this approach the drawer is placed on the left side.
An other approach can be to perform actions by pressing an drawer entry. In this situation you wont replace any fragments and only implement the drawer to the activities which should be able to perform this particular interaction (maybe: "send contact per a email")

Optimal way to implement Navigation Drawer in Android app

There are two ways of implementing the Navigation Drawer in the Android app
1) Create a single activity that sets the DrawerLayout as the content view and then have multiple fragments get swapped in and out of the same activity
2) Declare and define the Navigation Drawer in the BaseActivity and then have all activities inherit from the BaseActivity.
Are there performance considerations in these implementations?
No performance considerations for you to worry about. Implementation-wise it makes basically no difference, 2) would just be more convenient if you had multiple Activities with a NavigationDrawer. What you are describing are just two different use cases for a NavigationDrawer.
Regarding your questions
As I said you are just describing two different use cases for a NavigationDrawer:
1) Create a single activity that sets the DrawerLayout as the content
view and then have multiple fragments get swapped in and out of the
same activity
This would be an app where you have one MainActivity with a NavigationDrawer which is used to switch between the some content. The detail views in this case would not have a NavigationDrawer.
2) Declare and define the Navigation Drawer in the BaseActivity and
then have all activities inherit from the BaseActivity.
This describes an app which would have the NavigationDrawer to quickly switch between content from any level. You can just open the NavigationDrawer in a detail view and go directly to a different part of the app.
In the end whether you implement 1) or 2) really is just a matter of personal preference and convenience and most importantly how you want your app to work.
One thing I can add is that it is rather uncommon to have a NavigationDrawer at every level in your app. NavigationDrawers are supposed to be top level menus so the user can easily navigate between different parts of the app that have nothing inherently to do with each other. Once you are in a specific part of your app it is best practice to simply use drill-down navigation.

Why fragments, and when to use fragments instead of activities?

In Android API 11+, Google has released a new class called Fragment.
In the videos, Google suggests that whenever possible (link1, link2), we should use fragments instead of activities, but they didn't explain exactly why.
What's the purpose of fragments and some possible uses of them (other than some UI examples that can be easily be achieved by simple views/layouts)?
My question is about fragments:
What are the purposes of using a fragment?
What are the advantages and disadvantages of using fragments compared to using activities/views/layouts?
Bonus questions:
Can you give some really interesting uses for fragments? Things that Google didn't mention in their videos?
What's the best way to communicate between fragments and the activities that contain them?
What are the most important things to remember when you use fragments? Any tips and warnings from your experience?
#1 & #2 what are the purposes of using a fragment & what are the
advantages and disadvantages of using fragments compared to using
activities/views/layouts?
Fragments are Android's solution to creating reusable user interfaces. You can achieve some of the same things using activities and layouts (for example by using includes). However; fragments are wired in to the Android API, from HoneyComb, and up. Let me elaborate;
The ActionBar. If you want tabs up there to navigate your app, you quickly see that ActionBar.TabListener interface gives you a FragmentTransaction as an input argument to the onTabSelected method. You could probably ignore this, and do something else and clever, but you'd be working against the API, not with it.
The FragmentManager handles «back» for you in a very clever way. Back does not mean back to the last activity, like for regular activities. It means back to the previous fragment state.
You can use the cool ViewPager with a FragmentPagerAdapter to create swipe interfaces. The FragmentPagerAdapter code is much cleaner than a regular adapter, and it controls instantiations of the individual fragments.
Your life will be a lot easier if you use Fragments when you try to create applications for both phones and tablets. Since the fragments are so tied in with the Honeycomb+ APIs, you will want to use them on phones as well to reuse code. That's where the compatibility library comes in handy.
You even could and should use fragments for apps meant for phones only. If you have portability in mind. I use ActionBarSherlock and the compatibility libraries to create "ICS looking" apps, that look the same all the way back to version 1.6. You get the latest features like the ActionBar, with tabs, overflow, split action bar, viewpager etc.
Bonus 2
The best way to communicate between fragments are intents. When you press something in a Fragment you would typically call StartActivity() with data on it. The intent is passed on to all fragments of the activity you launch.
Not sure what video(s) you are referring to, but I doubt they are saying you should use fragments instead of activities, because they are not directly interchangeable. There is actually a fairly detailed entry in the Dev Guide, consider reading it for details.
In short, fragments live inside activities, and each activity can host many fragments. Like activities, they have a specific lifecycle, unlike activities, they are not top-level application components. Advantages of fragments include code reuse and modularity (e.g., using the same list view in many activities), including the ability to build multi-pane interfaces (mostly useful on tablets). The main disadvantage is (some) added complexity. You can generally achieve the same thing with (custom) views in a non-standard and less robust way.
A Fragment is a piece of an application's user interface or behavior that can be placed in an Activity which enable a more modular activity design. It will not be wrong if we say a fragment is a kind of subactivity.
Following are important points about a fragment:
A fragment has its own layout and its own behavior with its own lifecycle callbacks.
You can add or remove fragments in an activity while the activity is running.
You can combine multiple fragments in a single activity to build a multi-pane UI.
A fragment can be used in multiple activities.
The fragment life cycle is closely related to the lifecycle of its host activity.
When the activity is paused, all the fragments available in the acivity will also be stopped.
A fragment can implement a behavior that has no user interface component.
Fragments were added to the Android API in Android 3 (Honeycomb) with API version 11.
For more details, please visit the official site, Fragments.
Activities are the full screen components in the app with the toolbar, everything else are preferably Fragments.
One full screen parent activity with a toolbar can have multiple panes, scrollable pages, dialogs, etc. (all fragments), all of which can be accessed from the parent and communicate via the parent.
Example:
Activity A, Activity B, Activity C:
All activities need to have same code repeated, to show a basic
toolbar for example, or inherit from a parent activity (becomes
cumbersome to manage).
To move from one activity to the other, either all of them need to be in memory (overhead) or one needs to be destroyed for the other to open.
Communication between activities can be done via Intents.
vs
Activity A, Fragment 1, Fragment 2, Fragment 3:
No code repetition, all screens have toolbars etc. from that one activity.
Several ways to move from one fragment to next - view pager, multi pane etc.
Activity has most data, so minimal inter-fragment communication needed. If still necessary, can be done via interfaces easily.
Fragments do not need to be full screen, lots of flexibility in designing them.
Fragments do not need to inflate layout if views are not necessary.
Several activities can use the same fragment.
This is important information that I found on fragments:
Historically each screen in an Android app was implemented as a separate Activity. This creates a challenge in passing information between screens because the Android Intent mechanism does not allow passing a reference type (i.e. object) directly between Activities. Instead the object must be serialized or a globally accessible reference made available.
By making each screen a separate Fragment, this data passing headache
is completely avoided. Fragments always exist within the context of a
given Activity and can always access that Activity. By storing the
information of interest within the Activity, the Fragment for each
screen can simply access the object reference through the Activity.
Source: https://www.pluralsight.com/blog/software-development/android-fragments
Fragments are of particular use in some cases like where we want to keep a navigation drawer in all our pages. You can inflate a frame layout with whatever fragment you want and still have access to the navigation drawer.
If you had used an activity, you would have had to keep the drawer in all activities which makes for redundant code. This is one interesting use of a fragment.
I'm new to Android and still think a fragment is helpful this way.
I know this was already discussed to death, but I'd like to add some more points:
Frags can be used to populate Menus and can handle MenuItem clicks on their own. Thus giving futher modulation options for your Activities. You can do ContextualActionBar stuff and so on without your Activity knowing about it and can basically decouple it from the basic stuff your Activity handles (Navigation/Settings/About).
A parent Frag with child Frags can give you further options to modulize your components. E.g. you can easily swap Frags around, put new Frags inside a Pager or remove them, rearrange them. All without your Activity knowing anything about it just focusing on the higher level stuff.
Fragment can be thought of as non-root components in a composite tree of ui elements while activities sit at the top in the forest of composites(ui trees).
A rule of thumb on when not to use Fragment is when as a child the fragment has a conflicting attribute, e.g., it may be immersive or may be using a different style all together or has some other architectural / logical difference and doesn't fit in the existing tree homogeneously.
A rule of thumb on when to prefer Activity over Fragment is when the task (or set of coherent task) is fully independent and reusable and does some heavy weight lifting and should not be burdened further to conform to another parent-child composite (SRP violation, second responsibility would be to conform to the composite). For e.g., a MediaCaptureActivity that captures audio, video, photos etc and allows for edits, noise removal, annotations on photos etc and so on. This activity/module may have child fragments that do more granular work and conform to a common display theme.
Fragments lives within the Activity and has:
its own lifecycle
its own layout
its own child fragments and etc.
Think of Fragments as a sub activity of the main activity it belongs to, it cannot exist of its own and it can be called/reused again and again. Hope this helps :)
A fragment lives inside an activity, while an activity lives by itself.
If you've ever written front-end before, so used front-end components like(React, Vue or Angular). Think about fragments like reusable components within an activity.
1.Purposes of using a fragment?
Ans:
Dealing with device form-factor differences.
Passing information between app screens.
User interface organization.
Advanced UI metaphors.
Why fragments?
Fragments were created to replace most of the activity use cases. And see this Android Dev Summit session.
When to use fragments instead of activities?
Always, unless you really need an API that is only available in activity.

Categories

Resources