I have several Fragment that are outlined like this :
MainActivity
that contains a MainFragment
and a WebFragment
(just a fragment that has a webview inside of it) :
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/main_fragment"
android:name="com.citylifeapps.cups.MainFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment
android:id="@+id/venue_fragment"
android:name="com.citylifeapps.cups.WebFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</fragment>
</FrameLayout>
MainFragment
that contains a ListFragment
and a MapFragment
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
android:id="@+id/map_fragment"
android:name="com.citylifeapps.cups.MapFragment"
android:layout_width="match_parent"
android:layout_height="fill_parent" />
<fragment
android:id="@id/list_fragment"
android:name="com.citylifeapps.cups.ListFragment"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
</RelativeLayout>
My problem is the following scenario :
- Start the app,
MainFragment
starts with the Map and List in the same screen - click on a list item,
WebFragment
opens up - Click back,
MainFragment
appears - as expected - Click another back -
WebFragment
is shown again
The last step (4) is the problem. The expected behaviour is that from the MainFragment
(step 3), clicking back will close the app as it is the highest in the chain.
I assume I am doing something wrong with the back stack,
I am trying to debug it but it is extremely hard to debug.
Here is the FragmentManager log :
// Step 1
09-16 16:00:15.683: D/FragmentManager(22278): Op #0: HIDE WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:15.683: D/FragmentManager(22278): Op #1: SHOW MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:15.733: V/FragmentManager(22278): moveto ACTIVITY_CREATED: MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:15.733: V/FragmentManager(22278): moveto ACTIVITY_CREATED: MapFragment{41e68c60 #1 id=0x7f05002a}
09-16 16:00:15.733: V/FragmentManager(22278): moveto ACTIVITY_CREATED: SupportMapFragment{41e6adc8 #2 id=0x7f050084}
09-16 16:00:15.733: V/FragmentManager(22278): moveto ACTIVITY_CREATED: ListFragment{42058380 #3 id=0x7f05002b}
09-16 16:00:15.733: V/FragmentManager(22278): moveto ACTIVITY_CREATED: WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:15.733: V/FragmentManager(22278): hide: WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:15.733: V/FragmentManager(22278): show: MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:15.733: V/FragmentManager(22278): moveto STARTED: MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:15.733: V/FragmentManager(22278): moveto STARTED: MapFragment{41e68c60 #1 id=0x7f05002a}
09-16 16:00:15.733: V/FragmentManager(22278): moveto STARTED: SupportMapFragment{41e6adc8 #2 id=0x7f050084}
09-16 16:00:15.733: V/FragmentManager(22278): moveto STARTED: ListFragment{42058380 #3 id=0x7f05002b}
09-16 16:00:15.733: V/FragmentManager(22278): moveto STARTED: WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:15.733: V/FragmentManager(22278): moveto RESUMED: MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:15.733: V/FragmentManager(22278): moveto RESUMED: MapFragment{41e68c60 #1 id=0x7f05002a}
09-16 16:00:15.733: V/FragmentManager(22278): moveto RESUMED: SupportMapFragment{41e6adc8 #2 id=0x7f050084}
09-16 16:00:15.743: V/FragmentManager(22278): moveto RESUMED: ListFragment{42058380 #3 id=0x7f05002b}
09-16 16:00:15.743: V/FragmentManager(22278): moveto RESUMED: WebFragment{42037ea8 #4 id=0x7f050082}
// Step 2
09-16 16:00:28.967: D/FragmentManager(22278): Op #0: SHOW MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:28.967: D/FragmentManager(22278): Op #1: HIDE WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:28.977: D/FragmentManager(22278): Op #0: HIDE MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:28.977: D/FragmentManager(22278): Op #1: SHOW WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:28.977: V/FragmentManager(22278): Bump nesting of MainFragment{41e678a0 #0 id=0x7f050081} to 1
09-16 16:00:28.977: V/FragmentManager(22278): Bump nesting of WebFragment{42037ea8 #4 id=0x7f050082} to 1
09-16 16:00:28.977: V/FragmentManager(22278): show: MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:28.977: V/FragmentManager(22278): hide: WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:28.977: V/FragmentManager(22278): Bump nesting of MainFragment{41e678a0 #0 id=0x7f050081} to 2
09-16 16:00:28.977: V/FragmentManager(22278): Bump nesting of WebFragment{42037ea8 #4 id=0x7f050082} to 2
09-16 16:00:28.977: V/FragmentManager(22278): hide: MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:28.997: V/FragmentManager(22278): show: WebFragment{42037ea8 #4 id=0x7f050082}
// Step 3
09-16 16:00:39.238: D/FragmentManager(22278): Op #0: HIDE MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:39.238: D/FragmentManager(22278): Op #1: SHOW WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:39.238: V/FragmentManager(22278): Bump nesting of MainFragment{41e678a0 #0 id=0x7f050081} to 1
09-16 16:00:39.238: V/FragmentManager(22278): Bump nesting of WebFragment{42037ea8 #4 id=0x7f050082} to 1
09-16 16:00:39.238: V/FragmentManager(22278): hide: WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:39.238: V/FragmentManager(22278): show: MainFragment{41e678a0 #0 id=0x7f050081}
// Step 4
09-16 16:00:53.724: D/FragmentManager(22278): Op #0: SHOW MainFragment{41e678a0 #0 id=0x7f050081}
09-16 16:00:53.724: D/FragmentManager(22278): Op #1: HIDE WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:53.724: V/FragmentManager(22278): Bump nesting of MainFragment{41e678a0 #0 id=0x7f050081} to 0
09-16 16:00:53.724: V/FragmentManager(22278): Bump nesting of WebFragment{42037ea8 #4 id=0x7f050082} to 0
09-16 16:00:53.724: V/FragmentManager(22278): show: WebFragment{42037ea8 #4 id=0x7f050082}
09-16 16:00:53.724: V/FragmentManager(22278): hide: MainFragment{41e678a0 #0 id=0x7f050081}
I don't understand what's wrong, The only time I add the WebFragment to the back stack is when I click the list item and open it up in step 2. Also I assume that calling super.onBackPressed()
pops the back stack as well.
Here is the simplified version of my code :
public class MainActivity extends ActionBarActivity {
private boolean venueOrMapPageVisible = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
FragmentManager.enableDebugLogging(true);
getSupportFragmentManager().beginTransaction()
.hide(getVenueFragment())
.show(getMainFragment())
.commit();
}
@Override
public void onBackPressed() {
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
if (venueOrMapPageVisible) {
setDrawerIndicatorEnabled(true);
venueOrMapPageVisible = false;
}
super.onBackPressed();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (super.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case android.R.id.home:
if (venueOrMapPageVisible) {
onBackPressed();
}
break;
return false;
}
// called when a venue is clicked
@Override
public void onItemClick(JSONObject venue) {
if (venue != null) {
String vid = null;
try {
vid = venue.getString("key");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
openVenue(vid);
}
}
private void openVenue(String vid) {
getVenueFragment().loadUrl(Consts.venueUri(vid));
MainActivity.this
.getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right)
.hide(getMainFragment())
.show(getVenueFragment())
.addToBackStack(null)
.commit();
venueOrMapPageVisible = true;
// analytics open venue start time (set it only once)
if (CupsTracker.venueStartTime == 0L) {
CupsTracker.venueStartTime = System.currentTimeMillis();
}
}
private WebFragment getVenueFragment() {
return (WebFragment) getSupportFragmentManager().findFragmentById(R.id.venue_fragment);
}
private MainFragment getMainFragment() {
return (MainFragment) getSupportFragmentManager().findFragmentById(R.id.main_fragment);
}
public void moveToMapFragment() {
MapFragment mapFragment = (MapFragment) getSupportFragmentManager().findFragmentById(R.id.map_fragment);
ListFragment listFragment = (ListFragment) getSupportFragmentManager().findFragmentById(R.id.list_fragment);
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right)
.hide(listFragment)
.addToBackStack(null)
.commit();
mapFragment.getView().setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
venueOrMapPageVisible = true;
}
}
I suspect that since the MainActivity layout file contains both the MainFragment
and WebFragment
, when it is inflated, WebFragment somehow implicitly added to the back stack or something. Is it possible ?