2014-09-05 1 views
1

J'ai un android.support.v7.app.ActionBarActivity qui a un FrameLayout détenant un SupportMapFragment et android.support.v4.app.ListFragment.problèmes ActionBarActivity returnin à ListFragment pour api10f

J'instancier les deux fragments dans le OnCreate de 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"); 
     } 

Et afin d'éviter de recréer chaque fragment lorsqu'il est sélectionné, je cache/afficher en fonction de celui qui est sélectionné.

@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. 
} 

Tout cela fonctionne très bien. Je peux sélectionner chaque fragment en utilisant la liste déroulante dans ActionBar et manipuler l'interface utilisateur etc. Orientation changement fonctionne également bien. Le problème se produit lorsque le ListFragment est visible et l'application ouvre une nouvelle activité et la touche retour est pressée pour revenir à l'activité d'origine.

OU

le ListFragment est visible et la touche HOME est pressée et une tentative de rouvrir l'application dans la barre des tâches.

Le problème ne se produit pas avec le fragment de carte uniquement ListFragment. L'application fonctionne dans les émulateurs GenyMotion pour API17 +

L'application retourne à la fonction ListFragment, mais les contrôles de l'interface utilisateur (contrôles de la barre d'action et listes déroulantes d'activité, etc.) ne répondent pas et l'écran s'estompe et ne répond plus.

Il n'y a pas d'erreur LogCat.

Cela semble être un problème avec API10 et se produit lors du retour à ListFragment ??

sur Remplacements 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. 

cette question soulève un certain temps affiché de nouveau même problème que je rencontre: Back button very slow

+0

Comment allez-vous la mise en place de la gestionnaires d'événements pour les contrôles déroulants, etc.? Comment restaurez-vous les gestionnaires d'événements et reliez-vous les éléments avec les gestionnaires d'événements, repeuplant vos objets de classe lorsque l'activité/les fragments sont repris? Pouvez-vous montrer les méthodes pour OnResume, OnSaveInstanceState, OnRestoreInstanceState de votre activité et des fragments? – Bryan

Répondre

0

Enfin, je trouve une solution à ce problème. En résumé, le problème est survenu lors de la commutation entre SupportMapFragment et ListFragment. Les méthodes Hide/show de la classe FragmentTransaction ont été utilisées pour basculer entre les deux fragments stockés dans un seul FrameLayout. Cependant, si le SupportMapFragment était dans son état caché et que le contrôle était passé à une nouvelle activité, il y aurait un retard important à revenir et l'interface ne répondrait plus.

Il n'y avait aucun problème si le SupportMapFragment était visible. Cela a eu lieu pour un téléphone Android 2.3.3 (Samsung Galaxy) seulement et il n'y avait pas un problème avec les émulateurs en cours d'exécution HoneyComb +

Voir ci-dessous pour la description de la solution et le 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; 
}