Should Fragments Be Used In the Back Stack - android

I know I can use a Fragment and have it added to the back stack, like so:
Fragment fragment = MyFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_holder, fragment).addToBackStack("my_fragment").commit();
Then I can handle changes in onBackStackChanged:
#Override
public void onBackStackChanged() {
boolean hasBackStack = getSupportFragmentManager().getBackStackEntryCount() > 0;
handleBackStackChanges(hasBackStack);
}
But the nagging question I have is whether or not I should.
The initial reason for this question is because of my desire to implement a persistant navigation drawer. One that is available at any point within the application, even if the navigation drawer icon (hamburger icon) is not present, with a swipe from the left edge of the screen.
This leaves me with two options; first I can have a single Activity that has a navigation drawer and hosts all of the Fragments, or I can have multiple Activities that each contain a navigation drawer.
Initially I was drawn to the first option, considering the navigation drawer sample uses fragments for each drawer option. This method would also allow me to easily implement the navigation drawer icon animation in onBackStackChanged:
public void handleBackStackChanges(boolean hasBackStack) {
ObjectAnimator.ofFloat(mDrawerArrow, "progress", hasBackStack ? 0 : 1).start();
...
}
But the sample is essentially a "flat" application, it doesn't handle any back stack changes (except for back to the MainActivity, which doesn't have a navigation drawer). And upon further development I have come across some difficulties with using a single Activity. Especially when handling orientation changes, and changes within the Toolbar.
So now I am thinking it may be simpler to use multiple Activities. Every Activity would extend a custom NavigationDrawerActivity. The MainAcitivity would have a Fragment for each navigation drawer item. Then each subsequent Activity (called from one of the Fragments in the MainActivity) would have a NavigationDrawer of its own, with a reference to which navigation drawer item the original Activity was in.
I can see this route presenting its own problems as well. Handling the navigation drawer icon animation, and handling the back stack when an item is selected from the drawer.
My question is essentially this: has anyone faced these problems already, and is there a more concrete solution? Are there issues (performance related or otherwise) that I could run into when choosing one option over the other?

Related

Is it possible to partially transition to Android Nav Component

I'm trying to understand if it is possible to refactor an app, activity by activity to use the new nav component. I can see that it does support multiple activity design but only by creating a nav component for each one. That would mean the effort would need to be across the whole app in one sweep, which is not feasible.
Is there any other way?
I've encountered several problems navigating between activities that do not use the nav component and activities that do, such as how to pop back to a previous non nav activity from a nav activity using an up arrow or even displaying the up arrow in the home fragment of the second activity.
I tried to manually setDisplayHomeAsUpEnabled(true) and declare the parent activity in the Manifest but not only does that solution seem incredibly inaccurate (what if 2 different activities could potentially be parents?) but also forced me to add SINGLE_TOP attribute in order to return to previous state, in total seems like too many bandaids that will surely hit more blocks very soon...
Any suggestions are welcome.
Thanks!
So after about 2 days of searching and trying things I've found that the best option is to setup the toolbar with the nav component but also replacing the appbar config that uses the nav graph with a default builder - one which has an empty top level fragment list. This change essentially tells the nav component there is no top level fragment so always display the up arrow (at least thats my understanding). Also need to add an up arrow listener to pop the back stack to the previous activity if we detect an event at the start destination (entry fragment)
There is no need to make any manifest changes or set the appbarhome attributes which I found conflict with the Nav component behaviour..
Blockquote
private fun setToolbar() {
navController = findNavController(R.id.navigation_host_fragment)
setSupportActionBar(binding.toolbar)
binding.toolbar.setupWithNavController(
navController,
AppBarConfiguration.Builder().build() // Use Builder for empty top level list, up arrow display for home fragment.
)
binding.toolbar.setNavigationOnClickListener {
if (navController.currentDestination?.id == navController.graph.startDestination) {
onBackPressed()
} else {
navController.navigateUp()
}
}
}
Blockquote
Hope this helps others that ran into the same difficulties transitioning to using the new'ish Nav component!!!

android - How to implement navigation with bottom app bar

I have a project with the following 4 layouts:
I have actually 1 activity holding a bottom app bar and the NavHostFragment where the fragments get injected. The Main Fragment is the home view. There is a Management and a Setting fragment, both are top-level views like the home view but doesn't depend on each other. These 3 fragments can be switched by clicking an item in the nav drawer. For simplification, I'm trying the new navigation architecture component.
Now I have some design questions:
Should I move the bottom app bar into the fragments, cause they don't depend on each other and the FAB button has another action, otherwise I had to change the onClickListener in the activity when the fragments switch?
1.1 Or should I even show the bottom app bar in the management fragment? Maybe just the top bar with the Up caret.
1.2 Or bottom app bar + top bar and Up caret
1.3 and what about the drawer icon, should I display it in the Mgmt fragment
Should I use a fragment or an activity for the Settings fragment? When I use a fragment, I have to move the bottom app bar into the fragments. Otherwise, the bottom app bar would be visible in the Settings Fragment
The Management Fragment has just a recycler view. Clicking on an item should open a DetailView. Should I use a fragment or an activity here?
I read the doc about the navigation architecture component and there is a section about customizing the destination. Also, ich checked the source code and know that the fragments get replaced.
Further, I checked out some frequently used Apps how they implemented the navigation with a nav drawer and noticed, they all replace their fragments. Why does no one hide/show the fragments, is there a reason not to doing this?
Assume we have a fragment with a listview that holds data collected from a database or another expensive task. So wouldn't it be better to show/ hide these fragments instead of replacing it?
Sorry, it's my first app and I'm really confused about this topic, and it seems there are no official recommendations about it out there not even Material Design guidelines don't really make a reference about it.
How would you do it?
setupWithNavController on a Toolbar (or subclasses like BottomAppBar) only set up the Up icon and the title - they do not hook up menu items added to the Toolbar.
As per the Tie destinations to menu items documentation, you must set up your own listener and call onNavDestinationSelected(). For a BottomAppBar, that would be done by setting a Toolbar.OnMenuItemClickListener:
val navController = Navigation.findNavController(this, R.id.navigation_fragment)
myBottomBar.replaceMenu(R.menu.menu_with_nav_item)
myBottomBar.setupWithNavController(navController)
// Connect MenuItems to the NavController
myBottomBar.setOnMenuItemClickListener { menuItem ->
menuItem.onNavDestinationSelected(navController)
}

Show Navigation drawer in every activity - android studio

I have a problem...I am developing an app in android studio.In the meantime,there is already a navigation drawer in it.But the problem is, it only appears in the home screen.When it goes to another screen, the navigation drawer is not shown. I am new to android studio but i know some of Java languages.Can anyone help me with providing anything that would help me make the navigation drawer show in all of slides and pages in my app.
from docs
Navigation Drawer
The navigation drawer is a panel that displays the app’s main
navigation options on the left edge of the screen. It is hidden most
of the time, but is revealed when the user swipes a finger from the
left edge of the screen or, while at the top level of the app, the
user touches the app icon in the action bar.
for achieve what you asked you have to use Fragments
Fragment represents a behavior or a portion of user interface in an
Activity. You can combine multiple fragments in a single activity to
build a multi-pane UI and reuse a fragment in multiple activities. You
can think of a fragment as a modular section of an activity, which has
its own lifecycle, receives its own input events, and which you can
add or remove while the activity is running (sort of like a "sub
activity" that you can reuse in different activities).
see this examples for more details
1. Navigation Drawer - android hive
2. Navigation Drawer exp 2
3. Navigation Drawer exp 3
Refer this answer also
Answer
You have to add fragments in that activity where the navigation drawer exist. Whenver the user will click on the option in the navigation drawer the view should be changed by replacing with the required fragment.So by using the fragments user will stay on the same activity but just the views will be changed in that activity. you can refer to the fragments documentation provided by android developers. https://developer.android.com/guide/components/fragments.html

How to call navigation drawer in all my activities?

I have my MainActivity that contains a navigation drawer with items. When I click on an item,it opens up a new activity. This activity has its own layout file. I want to call the navigation drawer in this activity as well. How do I do that? Because I want to navigate through the app using the navigation drawer,rather than pressing back button all the time.
Let's say I have 2 activities, both of which I want to have the Navigation Drawer. In the layout.xml for each, I specified a DrawerLayout with the appropriate list view to hold my navigation options. Essentially, the Navigation drawer is made every time I switch between activities, giving the appearance that it is persisting. To make life a lot easier, I took the common methods required to set up the navigation drawer and put them in their own class: NavigationDrawerSetup.java. That way my activities can use the same custom adapter, etc.
Complete Reference : NavigationDrawer with Multiple Acivities

setRetainInstance in NavigationDrawer

I found a lot of informations about the setRetainInstance method, but I'd like to know how to implement this method in a Navigation Drawer Activity?
I basically have:
An Activity, that contains...
a NavigationDrawerFragment, that contains...
a TopLevelMapFragment (showing Google Maps).
My aim is to prevent a reload of the whole maps and its tracks when the user rotates the screen. What is the basic concept of setRetainingInstance in an Navigation Drawer Activity? Do I have to call setRetainingInstance(true) in the NavigationDrawerFragment AND the TopLevelMapFragment?
I finally found the solution to my Problem:
When I created the Navigation Drawer Activity, I relied on the default Navigation Drawer Activity-template of Android Studio. In this template, the FragmentTransaction-replace method is called each time the user clicks on an item in the Navigation Drawer. Problem: the replace-method destroys all the fragments that are in the specified container.
So if you want to keep your fragments alive, don't ever use the replace method. You have to use the methods add, show and hide instead.
In addition, I call the setRetainInstance(true)-method in my Google Maps-Fragment, so that the fragment stays alive when the user rotates the screen for example.

Categories

Resources