I have a android.support.v7.app.ActionBarActivity
that has a FrameLayout
holding a SupportMapFragment
and android.support.v4.app.ListFragment
.
I instantiate both fragments in the OnCreate of ActionBarActivity
if(mFM.findFragmentByTag("ListFragment")==null){
mPlaceListFragment = new PlaceListFragment_1();
mFM.beginTransaction().add(R.id.listfragment_container, mPlaceListFragment,"ListFragment").commit();
}else{
mPlaceListFragment = (PlaceListFragment_1)mFM.findFragmentByTag("ListFragment");
}
if(mFM.findFragmentByTag("MapFragment")==null){
mMapFragment = new map_fragment(); //always create map fragment
mFM.beginTransaction().add(R.id.mapfragment_container, mMapFragment,"MapFragment").commit();
}else{
mMapFragment = (map_fragment) mFM.findFragmentByTag("MapFragment");
}
And in order to avoid recreating each fragment when it’s selected I hide/show them depending on which one is selected.
@Override
public boolean onNavigationItemSelected(int i, long l) { //OnFragmentInteractionListener
FragmentTransaction ft = mFM.beginTransaction();
if(i==0){
//map
if (mPlaceListFragment.isVisible())ft.hide(mPlaceListFragment);
if (mMapFragment.isHidden())ft.show(mMapFragment);
}else{
//list
if (mPlaceListFragment.isHidden())ft.show(mPlaceListFragment);
if (mMapFragment.isVisible())ft.hide(mMapFragment);
}
ft.commit();
return true; //True if the event was handled, false otherwise.
}
This all works fine. I can select each Fragment using the dropdown in ActionBar
and manipulate UI etc. Orientation change also works ok.
The problem occurs when the ListFragment
is visible and the app opens a new Activity and the back key is pressed to return to the original Activity.
OR
the ListFragment is visible and the HOME button is pressed and an attempt is made to reopen the app from the task bar.
The problem doesn’t occur with the map fragment just the ListFragment. Also the app works for in GenyMotion emulators for API17+
The app returns to the ListFragment ok but the UI controls (actionbar controls and activity dropdowns etc.) are not responsive and the screen fades and becomes unresponsive.
There is no LogCat error.
It appears to be a problem with API10 and occurs when returning to the ListFragment??
Overrides on ActionBarActivity
@Override
protected void onResume() {
//activity - after onstart
super.onResume();
if(mAdView!=null) mAdView.resume();
FragmentTransaction ft = mFM.beginTransaction();
if(getSupportActionBar().getSelectedNavigationIndex()==0){
//show map
ft.show(mMapFragment);
ft.hide(mPlaceListFragment);
}else{
//show ListFragment
ft.show(mPlaceListFragment);
ft.hide(mMapFragment);
}
ft.commit();
}
@Override
protected void onPause() {
//activity
if(mAdView!=null) mAdView.pause();
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
// If the client is connected
if (mLocationClient!=null && mLocationClient.isConnected()) {
/*
* Remove location updates for a listener.
* The current Activity is the listener, so
* the argument is "this".
*/
mLocationClient.removeLocationUpdates(this);
mLocationClient.disconnect();
}
EasyTracker.getInstance(this).activityStop(this);//put as last statement
}
@Override
protected void onDestroy() {
//activity
if(mAdView!=null) mAdView.destroy();
super.onDestroy();
//clean the file cache when root activity exit
//the resulting total cache size will be less than 3M
if(isTaskRoot()){
AQUtility.cleanCacheAsync(this);
}
if (mLocationClient !=null && !mLocationClient.isConnected()) mLocationClient.disconnect();
}
********************************************************************
//All handlers are set in Oncreate of main ActionBarActivity e.g.
//ActionBar Spinner
********************************************************************
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
mSpinnerAdapter = ArrayAdapter.createFromResource(actionBar.getThemedContext(), R.array.action_list, android.R.layout.simple_spinner_dropdown_item);
}else{
mSpinnerAdapter = ArrayAdapter.createFromResource(actionBar.getThemedContext(), R.array.action_list, android.R.layout.simple_spinner_dropdown_item);
//mSpinnerAdapter = ArrayAdapter.createFromResource(actionBar.getThemedContext(), R.array.action_list, R.layout.navigation_spinner_item);
}
actionBar.setListNavigationCallbacks(mSpinnerAdapter, this);
********************************************************************
//other spinners and views belonging to main activity
********************************************************************
mSprSavedPlaces = (Spinner) findViewById(R.id.spr_saved_places);
mSprSavedPlaces.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
//stuff
}
//Also the Map and List fragments are repopuplated from via the main
//ActionBarActivity’s onSaveInstanceState and onRestoreInstanceState
//this seems to work ok.
this question posted a while back raises same issue as I'm experiencing: Back button very slow
At last I found a solution to this problem. In summary the problem occurred when switching between a SupportMapFragment and ListFragment. Hide/show methods of the FragmentTransaction class were used to toggle between both fragments stored in a single FrameLayout. However if the SupportMapFragment was in its hidden state and control was passed to a new activity and back again there would be a big delay coming back and the UI would be unresponsive.
There was no problem if the SupportMapFragment was visible. This occurred for an Android 2.3.3 (Samsung Galaxy) phone only and there wasn’t a problem with emulators running HoneyComb +
See below for solution description and code:
/**
* Show selected fragment and hide other.
*
* Could not use ft.hide/show for SupportMapFragment because this caused
* big delays coming back to main screen from other activities when the SupportMapFragment was
* in its hidden state. It also caused the UI to become unresponsive.
*
* I solved this by hiding/showing the SupportMapFragment by removing/adding the fragment for
* its container view. Working on 2.3.3 and Honeycomb --> KitKat emulators
*/
private void showFragment(Fragment fragmentIn) {
if (fragmentIn == null || mFragmentVisible == fragmentIn) {
return;
}
View mapView=mMapFragment.getView();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if(fragmentIn instanceof map_fragment){
//show map
if (mapView.getParent()!=mFragmentContainer) { //mFragmentContainer is FrameLayout
mFragmentContainer.addView(mapView);
}
ft.hide(mPlaceListFragment);
}else{
//show list
mFragmentContainer.removeView(mapView);
ft.show(mPlaceListFragment);
}
ft.commit();
mFragmentVisible = fragmentIn;
}