13

Attualmente sto utilizzando il Navigation Drawer per la mia APP per Android. Nel mio primo frammento, ho un frammento che carica i dati utilizzando l'API Graph di Facebook. Quindi, quando la mia app viene caricata per la prima volta, va prima al primo frammento.Stato frammento del cassetto di navigazione Android

First

Poi, io uso il cassetto di navigazione per fare clic su un altro frammento e visualizzarlo.

Second Fragment

E poi finalmente, ho riutilizzare il cassetto di navigazione per procedere di nuovo al primo frammento e visualizzarlo.

First Fragment

mio problema che sto affrontando è, come procedo per utilizzare il frammento che si è creata una volta invece di ricreare ogni volta che si seleziona la voce di navigazione cassetto. Il mio codice per la commutazione dei frammenti è come mostrato di seguito.

private void displayView(int position) { 
    // update the main content by replacing fragments 
    Fragment fragment = null; 
    switch (position) { 
    case 0: 
     fragment = new SelectionFragment(); 
     break; 
    case 1: 
     fragment = new HomeFragment(); 
     break; 
    case 2: 
     fragment = new PhotosFragment(); 
     break; 
    case 3: 
     fragment = new CommunityFragment(); 
     break; 
    case 4: 
     fragment = new PagesFragment(); 
     break; 
    case 5: 
     fragment = new SplashFragment(); 
     break; 
    default: 
     break; 
    } 

    if (fragment != null) { 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction() 
       .replace(R.id.frame_container, fragment).commit(); 

     // update selected item and title, then close the drawer 
     mDrawerList.setItemChecked(position, true); 
     mDrawerList.setSelection(position); 
     setTitle(navMenuTitles[position]); 
     mDrawerLayout.closeDrawer(mDrawerList); 
    } else { 
     // error in creating fragment 
     Log.e("MainActivity", "Error in creating fragment"); 
    } 
} 

ho notato che v'è infatti un'istanza "nuova" del frammento ogni volta ogni volta che viene selezionata l'opzione. Come faccio a implementare la logica di creazione dell'istanza Fragment ONCE e riutilizzarla, in modo da non dover caricare continuamente il frammento più e più volte.

+0

Hai visto qualche modo particolare per sostituire l'ArrayAdapter con un FragmentStatePagerAdapter? Mi stavo chiedendo anche questa stessa domanda, ma non ho visto nessuno davvero farlo, e nemmeno io (sono stato pigro a provare, non perché fosse impossibile.) – EpicPandaForce

risposta

17

Per chiunque incontri lo stesso problema con me, sono riuscito a trovare una soluzione.

Nel frame del contenitore, devo definire viste frammento specifiche che utilizzerò come mostrato di seguito.

Specific fragments

In ogni vista Frammento, ho da "link" con il vero e proprio frammento come illustrato di seguito tramite il "android: name" attribute.Do prendere nota del percorso la al frammento, esempio nel mio caso è com.example.confesssionsrp.SelectionFragment.

<fragment 
    android:id="@+id/selectionFragment" 
    android:name="com.example.confessionsrp.SelectionFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

Nella la MainActivity (o l'attività di dove stiamo visualizzando i frammenti), creare le variabili per ciascuno dei frammenti, come illustrato di seguito.

Variables

In seguito, nel onCreate del MainActivity (o la vostra attività specifica), inizializzare i vari frammenti come illustrato di seguito.

OnCreate

proseguire sulla creazione di un nuovo metodo chiamato "ShowFragment" come mostrato di seguito.

private void showFragment(int fragmentIndex, boolean addToBackStack) { 
    FragmentManager fm = getSupportFragmentManager(); 
    FragmentTransaction transaction = fm.beginTransaction(); 
    for (int i = 0; i < fragments.length; i++) { 
     if (i == fragmentIndex) { 
      transaction.show(fragments[i]); 
      if (Session.getActiveSession().isClosed()) { 
       mDrawerLayout 
         .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); 
      } 
     } else { 
      transaction.hide(fragments[i]); 
     } 
    } 
    if (addToBackStack) { 
     transaction.addToBackStack(null); 
    } 
    transaction.commit(); 
} 

Da allora nella commutazione dei frammenti, chiamata manualmente sul metodo "ShowFragment" con il frammento selezionato come mostrato di seguito.

Show Fragment

Fare tutto questo in generale, non si ripristinerà il Frammento ogni volta che l'abbiamo vista, e quindi è la soluzione alla answer.Thank voi per chi mi ha aiutato finora :)!

+0

La tua soluzione sembra molto buona. Lo sto provando ora ... lo voterò. :) –

+0

Questo è molto buono e sta salvando lo stato del frammento. –

+2

Non stiamo rendendo pesante l'applicazione creando tutti i frammenti? –

0

Sto usando il seguente codice:

@Override 
public void onNavigationDrawerItemSelected(int position) { 

    // update the main content by replacing fragments 
    FragmentManager fragmentManager = getFragmentManager(); 
    if(position==0){// selection of tabs content 
     fragmentManager 
     .beginTransaction() 
     .replace(R.id.container, 
       SimulatorFragment.newInstance(position + 1)).commit(); 
    }else if(position==1){ 
     fragmentManager 
     .beginTransaction() 
     .replace(R.id.container, 
       HudFragment.newInstance(position + 1)).commit(); 
    }else if(position==2){ 
     // Display the fragment as the main content. 
     fragmentManager 
     .beginTransaction() 
     .replace(R.id.container, 
       SettingsBasicFragment.newInstance(position +1)).commit(); 
    }else{ 

    } 
} 

È possibile sostituire con una nuova istanza per la prima volta e memorizzare il frammento, se non è nullo, quindi sostituire dal frammento memorizzato.

L'attività deve implementare NavigationDrawerFragment.NavigationDrawerCallbacks

Il costruttore frammento e metodi newInstance aspetto:

public final class HudFragment extends Fragment { 
/** 
* The fragment argument representing the section number for this 
* fragment. 
*/ 
private static final String ARG_SECTION_NUMBER = "section_number"; 

/** 
* Returns a new instance of this fragment for the given section number. 
* @param simulation 
*/ 
public static HudFragment newInstance(int sectionNumber) { 
    HudFragment fragment = new HudFragment(); 
    Bundle args = new Bundle(); 
    args.putInt(ARG_SECTION_NUMBER, sectionNumber); 
    fragment.setArguments(args); 
    return fragment; 
} 

public HudFragment() { 
} 

Per passare da frammenti codice che utilizzo questo metodo all'interno NavigationDrawerFragment:

/** 
* Select a different section 
* @param position 
*/ 
public void select(int position){ 
    selectItem(position); 
} 

private void selectItem(int position) { 
    mCurrentSelectedPosition = position; 
    if (mDrawerListView != null) { 
     mDrawerListView.setItemChecked(position, true); 
    }    
    if (mDrawerLayout != null) { 
     mDrawerLayout.closeDrawer(mFragmentContainerView); 
    } 
    if (mCallbacks != null) { 
     mCallbacks.onNavigationDrawerItemSelected(position); 
    } 
} 
+0

Ehi, grazie per l'aiuto ! Lo apprezzo davvero. Ma ho trovato un altro e più semplice modo di implementarlo. Grazie ancora per l'aiuto amico! :) –

0

La seconda opzione è iniziare con l'esempio di navigationDrawer offerto da Android SDK. Ho selezionato quel modello di attività durante la creazione del progetto e quasi tutto il codice della mia risposta precedente viene prodotto automaticamente.

Se si desidera mantenere i frammenti dopo la rotazione del dispositivo o simili, è una cosa diversa, è necessario quindi conservare i frammenti. In caso contrario, è sufficiente salvare la nuova istanza del frammento in una variabile e verificare se è nullo per crearne una nuova o utilizzare quella precedente.

0

Nel caso in cui qualcuno vuole un approccio diverso a questo: si potrebbe trovare il frammento sullo stack:

// check if this fragment is on the backstack to avoid creating a new one 
    Fragment foundFragment = fragmentManager.findFragmentByTag("unique_fragment_tag"); 
    if (foundFragment != null) { 
      fragmentManager.popBackStackImmediate("unique_fragment_tag", 0); 
      return; 
    } 
Problemi correlati