Navigation Controller: how to insert a fragment in the back stack - android

I'm programming deep link behavior where a particular link navigates the user to a video. In the normal flow, the user navigates to this video through a course details fragment containing a list of the videos.
However, the deep link flow obviously skips this screen, meaning that when the user backs out of the video, they are sent directly to home. I'd like to insert the course details screen into the backstack so that when the user backs out of the video, they are instead redirected to the course detail screen. What is the best way of doing this?
At the moment, my deep link code executes a navigation to course details screen right before the navigation to the video occurs.

You can make transaction fragments easier by using the following class (which is done with 4 methods in total) For more readability and simplified transaction.
https://github.com/mahditavakoli1312/FragmentTransaction---mahdi-tavakoli

Related

Deeplinking with Navigation component with Individual Stack

I have two urls which falls under the same deep link like below :
xxx.yyy.zzz/pages
xxx.yyy.zzz/how-deeplinks-work-exactly
Now the first one is a list of pages which goes to a fragment which lists the list of pages and second goes to a fragment which shows the details of that page.
Scenario :
https://github.com/android/architecture-components-samples/tree/master/NavigationAdvancedSample
I am following the above sample for having independent stacks for each tab.
When I have two different deep links for the above two links, it navigates to both the fragments. Like when I open the app with xxx.yyy.zzz/pages url it opens both the PagesFragment and DetailFragment one after another. So when I press back button from PagesFragment it navigates back to DetailFragment.
Now how do I handle these two scenario with deep links. If have both the deep links setup it navigates to both the screens one by one. I know I can change the path and add a prefix the page detail url(xxx.yyy.zzz/page/how-deeplinks-work-exactly), but is there anyway I can intercept the parsing logic or add some exclude condition to achieve this without changing the url scheme?
Edit : This is likely an issue with the Navigation logic (NavigationExtensions.kt) written for having individual stack.
You shouldn't use NavigationExtensions.kt anymore, instead increase your navigation component library version. Check this article out: https://medium.com/androiddevelopers/navigation-multiple-back-stacks-6c67ba41952f
Perhaps upgrading the lib version also changes the behaviour of your app with respect to the deep links

Managing multiple hierarchies using Fragment Manager and DrawerLayout

I have an app that is using a DrawerLayout and each item in the drawer will load a Fragment. The structure looks like:
News -> News Story
Photos -> Gallery -> Photo
Events -> Event
Directory -> User Type -> User Profile
Each top level is an item in the Drawer, tapping one will take you to that fragment and you can go deeper into that section by adding additional fragments on the stack, e.g. navigating from Photos to a Gallery to a photo in that gallery.
It gets confusing when I need to manage the navigation of each of these sections as individual stacks. On iOS I would use a UINavigationController for each section so that I could manage either separately. But on Android I am not sure how to do this. It is almost like I need to have multiple Fragment Manager instances. Without this, I feel I will run into issues when:
A user is deep into the News stack then switches to Photos, they navigate deep into that stack, but want to return to where they were in the News section. How can they return to that stack? And, navigate back up the News stack?
This seems like a major design issue with Android, unless I am missing something. Any ideas on how to solve this?
EDIT:
Basically I want what they showed at Google I/O:
https://www.youtube.com/watch?v=XpqyiBR0lJ4
I just built an app with this design. I just kept adding fragments to the stack when the user was in 'News' or any sub category of 'News'. If the user navigated to 'Photos' I would just pop all of the fragments from stack with:
getFragmentManager().popBackStackImmediate(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
and start adding to the stack again. I'm not sure if this is the 'right way' but it worked fine for me. I would just log the last fragment they were viewing in 'News' and restore it when they return to 'News' if that's the behavior you are looking for.
I managed multiple categories/sub-cats just fine using one Activity.

How to use Fragments

I'm trying to wrap my head around when exactly I should use Fragments and if I'm going to use them how to do so properly.
To my understanding Fragments should be used if you want a more flexible UI as it will be easier when rotating the device and easier to have your layout work with multiple screen sizes.
It seems to me that it is good to use them because you could have an app with ONE activity and multiple Fragments so the activity will be able to get calls from callbacks while the Fragments change what the user is seeing and interacting with. If I were to compare two apps, one made with Activities and the other with Fragments I would imagine to see something like this:
Activity app has a log in screen. The user can log in and it brings them to the main menu (New Activity). Once there they select the Friend button which brings them to a new Friend activity.
Fragment app has an Activity that loads the Log in Fragment into it's FrameLayout. The Log in Fragment allows the user to log into their account. Once it logged in, it replaces the Log in Fragment in the FrameLayout with the Main Menu Fragment. User presses Friend button, it opens the new Friend Fragment in the Activities FrameLayout. In this case all the work is being done in the Fragments but the Activity is just really holding them.
Please tell me why this is the incorrect use... or why this is correct.
Cheers
Take a look at the official Fragments doc. Short answer: always use Fragments. Fragments are better for reusability, flexibility, etc., etc.

How to switch between different activities like tabs in android?

I need to develop an application which contain these tabs shown in the image. Each tab contain a form which will be filled by the user.User can switch to any tab.
User click Activity1, Activity 1 gets displayed and user enters some data; then user press Activity 2, activity 2 gets displayed, user press Activity1 again, Activity 1 gets displayed with the data entered by the user(not the blank activity).
At the end when user click "Save" I need to get all the data from these activities and save it somewhere.
I have worked a lot in java but new to android, I am stuck in developing the UI for this scenario. However I have done this many times in iOS.
Anybody please share your experience of developing such UI.
Thanks,
Fragments will be more suitable for this scenario, the benefit are
They are light weight and faster
Managed automatically by the FragmentManager.
Data Sharing between Fragments is smoother and simpler than it is for Activities
They don't complicate the Architecture of the Application
You can have as many Fragments as you want in you Activity. Following two links can be useful for you.
A similar Thread
A Good Tutorial
Another good tutorial
If even after that you decide to use Activities, You need to think

Android - Temporal & Ancestral Navigation with ViewPager & Fragments

I'm trying to work out the best way to implement the 'ancestral' and 'temporal' navigation (utilising the up button and back buttons), for a music player I'm working on.
Currently, the user is presented with a viewpager, and can page between three main fragments (ArtistMain, AlbumMain and SongMain). Upon choosing an item inside that view, a fragment transaction occurs, and the viewpager goes out of view, replaced by a new fragment (AlbumSub, Songsub or player, depending on where the user came from). The user can then navigate deeper, until a song is chosen, and then they are taken to the 'player' screen.
I guess the question is: How do I implement all of this conditional navigation?
I'm fairly new to android and programming in general, and I just can't seem to come up with an efficient way to achieve this. At the moment, as each fragment is brought into view, the app is checking to see where the user just came from, and then determines where the user should be taken if back or home is called. This means I have a booleans like "fromArtistMain", "fromAlbumSub", and I'm checking for things like "fromSongSub && fromPlayer".. it's all turning into a bit of a mess.
I've drawn a diagram (in paint, sorry!!), to depict the navigation I'm trying to achieve. The yellow represents the 'up' button press, the red is the 'back' button press, and blue is just normal navigation. The green arrows are meant to represent the view paging:
Any advice is welcome. It might take something really simple that I've just overlooked.
Thanks for your time.
Edit:
I have been adding fragments to the backstack, and using popBackStack() calls, the problem is that popping the backstack is not necessarily the correct option in each case.
I've currently got a whole mess of code trying to determine whether a transaction should be added to the backstack in the first place.
Consider the following:
User chooses a song straight from 'SongMain', and is taken to 'Player'. Now using the home button should (in my mind), take the user to SongSub (the list of songs from the album that the chosen song belongs to). Now if the user navigates up again, they will be taken to 'AlbumSub', the list of Albums by that artist. This is a fragment transaction, but adding to the backstack would mean the user would be taken down a level on back press (which I think would be unexpected). So in this case I don't add that particular transaction to the backstack - seems fine, but there are quite a few different cases, and combined with a viewpager at the top which needs to come in and out of visibility, the code gets really messy.
All of this means a whole bunch of conditionals determining where the user came from and which path they took to get there..
Would it be wise to have a bunch of booleans in the host activity which get set depending on where the user has navigated, and then checking those booleans to see if a transaction should be added tot he backstack? This is kind of what I already have, but it seems really inefficient.
What you're looking into is called the Back stack. You can read more about it here at developer.android.com.
If you use a single Activity to host each of these Fragments then you can modify your code to explicity add your Fragments to the Fragment Back stack using code like so:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, fragment);
transaction.addToBackStack("NameOfFragment");
transaction.commit();
So, if you do the above code with Fragments like so:
Fragment1 -> Fragment2 -> Fragment3 -> Fragment4
Then from Fragment4 if you call this method:
getSupportFragmentManager().popBackStackImmediate();
Then Fragment4 will be finished and Fragment3 will restart. Simple. You can have this line called from a button click or you can override the behaviour of the back button to call it.
Please note in the examples I've used the function getSupportFragmentManager() which is a method name in the Compatibility Package. If you're not using the Compatibility Package then you can instead call getFragmentManager().
EDIT
The problem with the navigation you envisage is that breaking out of the backstack paradigm half way through means that your app will "Act Differently" than the rest of the OS. This is by and large discouraged by Google. But then again, saying that, I do exactly the same in my app for very similar reasons :).
When you navigate "up", along one of your yellow lines, you are following a discrete link (so, startActivity(new Intent(this, SongSub)); or whatever) and you want this to "break" the backstack.
It's at this stage you can make a decision about how you want to go forward:
You can start a Task (backstack) using SongSub as 0th item. This is from memory what the Google Music app does and you're right, it's annoying. When you press back it should technically exit the app. Yuk. IMO if you're in an obvious page hierarchy, back should always navigate down the hierarchy over exiting the app.
You can start a new Task using ArtistMain as the 0th element and layer fragments discretely ontop before commiting your transaction, in effect creating a new backstack each time you go "up" rather than "back" (your backstack would now be ArtistMain->ArtistSub->SongSub). This is what I think your trying to ask here. It's possible but it's messy.
You can create a more linear structure (probably the best idea if possible). Ignore the backstack paradigm, make "back" and "up" always go up a level no matter where you came from (Player always goes to SongSub, SongSub always goes to AlbumSub). This will give the user the least confusing and most transparent (as well as easiest to implement) experience - the user will learn quickly how to navigate (and how many "backs" to press) to get to where they want to be.

Categories

Resources