In the "System Back after cross navigation to lower hierarchy levels" section of the Navigation Drawer, they say:
If the user navigates to a lower hierarchy screen from the navigation drawer and the screen has a direct parent, then the Back stack is reset and Back points to the target screen’s parent. This Back behavior is the same as when a user navigates into an app from a notification.
I know the back stack can be reset by starting an activity with FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK, but that does not seem to be usable here, as it would not create a back stack for Lower 1.1.1.
Any idea how to remove TopView2 from the stack and at the same time add the TopView1 -> Lower 1.1 back stack when starting Lower 1.1.1 ? I'm expecting a simple solution, considering this is mentioned in the Navigation Drawer document.
A task is a collection of activities that users interact with when trying to do something in your app. These activities are arranged in a stack—the back stack—in the order in which each activity is opened.
The easiest way is to give the LoginActivity a “android:noHistory = true” attribute in the manifest file. That instructs Android to remove the given activity from the history stack thereby avoiding the aforementioned behavior altogether.
Declare Activity A as SingleTop by using [android:launchMode="singleTop"] in Android manifest. Now add the following flags while launching A from anywhere. It will clear the stack.
EDIT Synthesized version:
1)Declare the hierarchical navigation structure of your app in your manifest file.
2)The root activity of your app should perform a view switch between the TopViews in your app hierarchy.*
3) Activities lower in the hierarchy should perform 'Selective Up' navigation.
*Important: you should not add transactions to the back stack when the transaction is for horizontal navigation such as when switching tabs or navigation drawer top views.
Full description:
You should avoid the use of Intent Flags with the new navigation patters like Navigation Drawer for the next reasons:
launchMode
.Instead, opt for the new Navigation API:
<activity>
in your manifest.NavUtils
.TaskStackBuilder
offers additional utilities for cross-task navigation.So to answer your question the general idea is:
1) You need to declare the logical parent of each activity in your manifest file, using the android:parentActivityName
attribute (and corresponding <meta-data>
element) like:
<application ... > ... <!-- The main/home activity (it has no parent activity) --> <activity android:name="com.example.myapp.RootDrawerActivity" ...> ... </activity> <!-- A child of the root activity --> <activity android:name="com.example.myapp.Lower11 " android:label="@string/lower11" android:parentActivityName="com.example.myapp.RootDrawerActivity" > <!-- Parent activity meta-data to support 4.0 and lower --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myapp.RootDrawerActivity" /> </activity> <activity android:name="com.example.myapp.Lower111 " android:label="@string/lower111" android:parentActivityName="com.example.myapp.Lower11" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myapp.Lower11" /> </activity> </application>
2) In your root Activity, drawer item selection should initiate a 'view switch' action by replacing the Activity's current fragment content.
A view switch follows the same basic policies as list or tab navigation in that a view switch does not create navigation history. This pattern should only be used at the root activity of a task, leaving some form of Up navigation active for activities further down the navigation hierarchy (In your case Lower 1.1 & Lower 1.1.1). The important thing here is that you don't need to remove TopView2 from the stack but to perform a view switch as commented before passing the position of the view (or fragment id) as an extra.
In your root Activity do something like this:
@Override protected void onDrawerItemSelected(int position) { // Update the main content by replacing fragments CategoryFragment fragment = new CategoryFragment(); Bundle args = new Bundle(); args.putInt(RootDrawerActivity.ARG_SORT, position); fragment.setArguments(args); FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.content_frame, fragment).commit(); // Update selected item and title, then close the drawer setDrawerItemChecked(position, true); setTitle(getResources().getStringArray(R.array.drawer_array)[position]); closeDrawer(); }
3) Then lower in the hierarchy (i.e. Lower1.1) you should perform 'Selective Up' navigation, recreating the task stack in the process.
Selective Up allows a user to jump across an app's navigation hierarchy at will. The application should treat this as it treats Up navigation from a different task, replacing the current task stack (This is what you want!) using TaskStackBuilder or similar. This is the only form of navigation drawer that should be used outside of the root activity of a task.
@Override protected void onDrawerItemSelected(int position) { TaskStackBuilder.create(this) .addParentStack(RootDrawerActivity.class) .addNextIntent(new Intent(this, RootDrawerActivity.class) .putExtra(RootDrawerActivity.ARG_SORT, position)) .startActivities(); }
Refs:
http://developer.android.com/training/implementing-navigation/ancestral.html https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With