Dynamically set parent activity

So, at the moment I have activity that can be achieved from two different actions, the problem is that I can only set one action as a parent action in the XML manifest file. Obviously, this is a bad UX / UI design, because an activity can send the user back to the wrong action that they had before, and so I'm trying to dynamically establish which activity is the parent.

The problem is that I'm not quite sure how to do this, whether in code or XML, so any pointers are evaluated. :)

+42
android
04 Oct '13 at 14:44
source share
7 answers

The game has two concepts: "Up" and "Back". "Back" is obvious: take me to where I was shortly before I arrived here. Usually you don’t need to worry about Back, as the system will handle this just fine. "Up" is not so obvious - it is similar to Zoom Out - from an element to a collection, from a detail to a wider image.

Which one is right for your use case?




According to the comment below: the up button pulls the destination from the Android manifest, but can be configured programmatically .

+7
04 Oct '13 at 15:47
source share

For future readers, here is an example of how to really implement the official / correct decision in accordance with the developer's guides (scroll to the point starting with "This is suitable when parenting activity can be different ... ").

Please note that this solution assumes that you are using the Support Library to implement your ActionBar and that you can at least set the default parent activity in your manifest XML file for backup if the action you perform is in the "task" that does not belong to your application (read the related documents for clarification).

 // Override BOTH getSupportParentActivityIntent() AND getParentActivityIntent() because // if your device is running on API 11+ it will call the native // getParentActivityIntent() method instead of the support version. // The docs do **NOT** make this part clear and it is important! @Override public Intent getSupportParentActivityIntent() { return getParentActivityIntentImpl(); } @Override public Intent getParentActivityIntent() { return getParentActivityIntentImpl(); } private Intent getParentActivityIntentImpl() { Intent i = null; // Here you need to do some logic to determine from which Activity you came. // example: you could pass a variable through your Intent extras and check that. if (parentIsActivityA) { i = new Intent(this, ActivityA.class); // set any flags or extras that you need. // If you are reusing the previous Activity (ie bringing it to the top // without re-creating a new instance) set these flags: i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); // if you are re-using the parent Activity you may not need to set any extras i.putExtra("someExtra", "whateverYouNeed"); } else { i = new Intent(this, ActivityB.class); // same comments as above i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); i.putExtra("someExtra", "whateverYouNeed"); } return i; } 

NOTE. If you do not set the default parental activity in the XML manifest file, you will also need to implement onCreateSupportNavigateUpTaskStack () , since the system will not have the idea of ​​creating a freeze frame for your task. I have not provided a single example for this part.

My thoughts on solutions like finish()

Looking for a solution to this problem, I came across several answers that advocate a strategy for overriding onOptionsItemSelected() and intercepting the android.R.id.home button so that they can simply finish() current Activity back to the previous screen.

In many cases, this will lead to the desired behavior, but I just want to point out that this is definitely not the same as the correct rewind. If you switched to a child activity through one of the parent actions, then yes finish() will return you to the previous previous screen, but what if you entered the child activity through a notification? In this case, finish() ing by pressing the UP button, you will be taken back to the main screen or to any other application that you viewed before you clicked the notification, instead it should send you to the appropriate parental activity in your application.

+39
Feb 05
source share

Thus, you can dynamically navigate through parent activity:

 getActionBar().setDisplayHomeAsUpEnabled(true); @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar Up/Home button case android.R.id.home: finish(); return true; } return super.onOptionsItemSelected(item); } 

NOTE. It redirects you to the activity or fragment from where you came from, regardless of whether it is a parent or not. When you click on the action bar, the Up / Home button will simply complete the current operation.

+21
Nov 11 '14 at 12:45
source share

To learn how to use Up Navigation correctly, see this Android Dev guide.

Please note that there is a big mistake in the aforementioned Android Dev Guide, as the functions of NavUtils work differently for ICS (and below) and JellyBean (and above). This flaw in NavUtils is beautifully explained here.

+4
Apr 17 '14 at 17:13
source share

The override method is getParentActivityIntent.

Here is my code and it works great.

 @Override public Intent getParentActivityIntent() { Intent parentIntent= getIntent(); String className = parentIntent.getStringExtra("ParentClassSource"); Intent newIntent=null; try { //you need to define the class with package name newIntent = new Intent(OnMap.this, Class.forName(className)); } catch (ClassNotFoundException e) { e.printStackTrace(); } return newIntent; } 

From parental actions;

 Intent i = new Intent(DataDetailsItem.this, OnMap.class); i.putExtra("ParentClassSource", "com.package.example.YourParentActivity"); startActivity(i); 
+3
Jan 03 '15 at 8:49
source share

Typically, an activity type of "detail" should provide upward navigation if it has nested / linked content. The back system is handled by the system, so you don’t have to worry about that.

Now there are several ways to do this for the extra effort to support the up navigation:

  • An action that has parent activity defined in AndroidManifest.

     Your Android Manifest --------------------- <activity android:name="com.example.app.DetailActivity" android:parentActivityName="com.example.app.MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.app.MainActivity" /> </activity> Your Detail Activity -------------------- @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); } 

    This works well if only one parent action means that (DetailActivity) always runs from (MainActivity). Otherwise, this solution will not work if (DetailActivity) is launched from different places. More details here: http://developer.android.com/training/implementing-navigation/ancestral.html

  • (Simple and recommended) activity with fragments of fragments and fragments:

     Your Detail Activity -------------------- protected void replaceFragment(Bundle fragmentArguments, boolean addToBackStack) { DetailFragment fragment = new DetailFragment(); fragment.setArguments(fragmentArguments); // get your fragment manager, native/support FragmentTransaction tr = fragmentManager.beginTransaction(); tr.replace(containerResId, fragment); if (addToBackStack) { tr.addToBackStack(null); } tr.commit(); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; } return super.onOptionsItemSelected(item); } 

    In this solution, if the user presses back, the fragment will slip out of the backstack fragment, and the user will be returned to the previous fragment, while remaining in the same activity. If the user presses up, the action is rejected, and the user returns to the previous action (being the parent action). The key here is to use the Fragment as your user interface and activity as the fragment host.

Hope this helps.

+2
Jan 13 '16 at 19:16
source share

You will need to track parental activity. One way to do this is to keep it as optional in the intent that you create to trigger the child activity). For example, if Activity A starts Activity B, store the intent in the intent created for B. Then in B onOptionsItemSelected , where you handle the up navigation, retrieve the intent, and start it using the desired intent flags.

The next post has a more complex use case with a chain of child actions. It explains how you can go to the same or a new instance of the parent and complete the intermediate steps in doing so.

Android for multi-parent activity navigation

+1
Sep 10 '15 at 0:50
source share



All Articles