Issue
I have a system which has several Activity
, Activity X
, Activity A
, Activity B
, and Activity Y
. Activity X
consist of list of A
. If we click on A
, it will go to Activity A
. Activity A
consist of list of B
. If we click on B
, it will go to Activity B
. Activity B
will also consist of list of B
. So, if we click B
on Activity B
, it will go to Activity B
. It is possible to end up the stack like this: X -> A -> B -> B -> B -> B -> B
. According to proper navigation by Android, if we click Up
on Activity B
, it should go to Activity A
, no matter how deep the stack is. So, every B
on the previous stack should end up on A
. Up until now, it's simple. I just need to set the parent class of Activity B
as Activity A
.
The problem is I can go to Activity B
from Activity Y
. If I open the Activity B
from Activity Y
, this Activity B
is not always know how to open Activity A
because the parent of B
can be another B
or A
. B
only know his parent. The problem is how to detect that Activity A
is reachable automatically without creating a new instance from Activity B
? This way, I can make my code like the following on Activity B
.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if (canGoUpToActivityA()) { // this means this Activity B is opened from Activity A directly (A -> B) or indirectly (A -> B -> ... -> B), not from Activity Y
NavUtils.navigateUpFromSameTask(this);
return true;
} else {
Intent intent;
if (TYPE_B.equals(mParent.getType())) {
intent = new Intent(this, ActivityB.class);
} else {
intent = new Intent(this, ActivityA.class);
}
intent.putExtra(EXTRA_ITEM, mParent)
startActivity(intent);
return true;
}
default:
return super.onOptionsItemSelected(item);
}
}
EDIT
If anybody down voting me because they think the solution is as simple as singleTop
to Activity A
, that's mean you guys don't understand my problem. See the last sentence of my first paragraph. I don't have any problem with going up from Activity B
to Activity A
, no matter how deep it is if Activity B
is opened from Activity A
.
Without the above onOptionsItemSelected
, I can go up to Activity A
from Activity B
if Activity B
is opened from Activity A
directly (A -> B)
or indirectly (A -> B -> ... -> B)
. This is not my problem.
The problem comes when I opened Activity B
from Activity Y
. I can't just go back to Activity A
because Activity A
rely on information from Activity X
. If I open Activity B
from Activity Y
, then I go up, I should go to the parent of Activity B
, where it can be A
or another B
.
The above code without canGoUpToActivityA()
part will solve my problem. With that code, when I open Activity B
from Activity Y
, then going up should always go to the parent of B
. That's already correct (B
only know its parent, which can be not A
).
But, when I open Activity B
from Activity A
, then I go up, it will launch the parent of Activity B
. If I open Activity B
from Activity A
directly (A -> B), it's is indeed what I want. But, when I open Activity B
from another Activity B
(A-> B -> ... -> B), that's the problem. Because I should go up to Activity A
, not the parent of Activity B
which can be another Activity B
.
Solution
I'm still not clear on what exactly you want, so I'll break this up into snippets:
If you want to launch a parent of Activity B
and ensure that it isn't "launching itself", you can use the singleTop
flag as noted by others to ensure that only one instance of B
is ever on the top. You mentioned you don't have an issue with that, but you've listed that as an example, so just keep that in mind.
You've also mentioned that you check if the parent is A
before launching Activity A
. If all you want to do is actually launch the previous activity in the stack, there is no need for an Intent. Just finish your activity and it will exit the stack, showing the previous activity.
If you have a set activity that you should launch when going back, you can simply launch it with an intent. At this point, it doesn't matter what the previous activity is, because you are explicitly starting an activity for a given class. Again, you may look at the FLAG_ACTIVITY_REORDER_TO_FRONT flag to ensure that an existing activity is not recreated.
Lastly, if you have some complex logic that requires you to know the full stack history, you can always pass data through your bundle. A simple example is an arraylist of the simple class name so you know everything in the current task.
Edit: Since you've also added that you depend on information from previous classes, I take it that you need more than just the class name.
Note that you can always pass data through the bundles so that they are retained through all subsequent activities. You can also pass all the current data by calling putExtras.
And if your entire flow is geared towards going to a child and then passing data back to a parent, consider using [startActivityForResult](https://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int)). That way, you can set result codes and data and finish your activity to directly pass information to the previous activity, without launching a new intent in a forward flow manner.
Answered By - Allan W
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.