2012-12-12 14 views
13

Ho visto alcune domande su SO su Frammenti e ancora non riesco a capire se quello che voglio fare è possibile, e più così se il mio design il modello è solo imperfetto e ho bisogno di rielaborare l'intero processo. Fondamentalmente, come la maggior parte delle domande che sono state poste, ho un ActionBar con NavigationTabs (usando ActionBarSherlock), quindi all'interno di ogni Tab c'è una FragementActivity e poi FragmentActivities spinge nuovi Fragments quando viene selezionata una riga (sto tentando di ricreare un progetto iOS in Android ed è solo un'app di base basata sulla navigazione con alcune schede che consentono di approfondire informazioni specifiche). Quando faccio clic sul pulsante Indietro sul telefono viene caricato il frammento precedente ma il frammento viene ricreato automaticamente (quindi i servizi Web vengono richiamati di nuovo per ogni vista) e questo non è necessario poiché le informazioni non cambieranno in una vista precedente quando andando indietro. Quindi in pratica quello che voglio capire è come impostare i miei frammenti in modo tale che quando spingo il pulsante indietro sul telefono, il frammento precedente sia appena estratto con gli elementi precedenti già creati. Qui di seguito è il mio codice corrente:Frammento Android, tornare indietro senza ricreare/ricaricare Frammento

//This is from my FragmentActivity Class that contains the ActionBar and Tab Selection Control 
    @Override 
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 
    // TODO Auto-generated method stub 
    int selectedTab = tab.getPosition(); 

    if (selectedTab == 0) { 
     SalesMainScreen salesScreen = new SalesMainScreen(); 
     ft.replace(R.id.content, salesScreen); 
    } 
    else if (selectedTab == 1) { 
     ClientMainScreen clientScreen = new ClientMainScreen(); 
     ft.replace(R.id.content, clientScreen); 
    }..... 

    //This is within the ClientMainScreen Fragment Class, which handles moving to the Detail Fragment 
    row.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          //Do something if Row is clicked 
          try{ 
           String selectedClientName = clientObject.getString("ClientName"); 
           String selectedClientID = clientObject.getString("ClientID"); 
           String selectedValue = clientObject.getString("ClientValue"); 
           transaction = getFragmentManager().beginTransaction(); 
           ClientDetailScreen detailScreen = new ClientDetailScreen(); 
           detailScreen.clientID = selectedClientID; 
           detailScreen.clientName = selectedClientName; 
           detailScreen.clientValue = selectedValue; 
           int currentID = ((ViewGroup)getView().getParent()).getId(); 
           transaction.replace(currentID,detailScreen); 
           transaction.addToBackStack(null); 
           transaction.commit(); 

          } 
          catch (Exception e) { 
           e.printStackTrace(); 
          } 
         } 
        });.... 

    //And then this is the Client Detail Fragment, with the method being called to Call the Web Service and create thew (since what is displayed on this screen is dependent on what is found in the Web Service 
      @Override 
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) { 
    return inflater.inflate(R.layout.clientdetailscreen, group, false); 
} 

@Override 
public void onActivityCreated (Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    //Setup Preferences File Link 
    this.preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 

    //initialize the table object 
    mainTable = (TableLayout)getActivity().findViewById(R.id.mainTable); 

    //setup the detail table 
    setupRelatedClientSection(); 

} 

pagina dettagliata client può quindi drill-down ancora una volta, utilizzando lo stesso metodo della schermata principale del client, ma quando torno da quella nuova schermata al dettaglio Filtra la seuptRelatedClientSection () viene chiamato di nuovo il metodo e quindi l'intero frammento viene ricostruito quando in realtà voglio solo tirare su una versione salvata di quello schermo. Questo è possibile con il mio setup attuale, o ho affrontato questo nel modo sbagliato?

risposta

7

Credo che stiate cercando show() e hide().

Penso che si possano ancora aggiungere al backstack.

transaction.hide(currentFragment); 
transaction.show(detailScreen); 
transaction.addToBackStack(null); 
transaction.commit(); 

ho avuto il mio codice da guardare, ma credo che questo è come sarebbe andata ... Provalo meno che qualcun altro ha un modo migliore. Non ho provato il backstack con show() hide() ma credo che tengano le modifiche che sono state apportate prima del commit delle transazioni e le annulleremo se viene premuto il pulsante back. Per favore, torna da me per questa causa, mi interessa sapere.

È inoltre necessario assicurarsi che il frammento di dettaglio venga creato prima di chiamare questo. Dato che si basa sul clic di alcuni oggetti, probabilmente dovresti creare il frammento di dettagli ogni volta che fai clic per assicurarti che venga creato il frammento di dettagli corretto.

+4

ho usato .add() invece che .Show(). Dal secondo frammento, quando ho premuto il pulsante indietro, è andato al primo frammento e non si è aggiornato. – Sri

0

Hai ragione, c'è stata una serie di domande precedenti/documentazione sul tema;)

La documentazione su frammenti, in particolare la sezione sulle transazioni e Stato di risparmio, vi guiderà alla risposta.

http://developer.android.com/guide/components/fragments.html#Transactions

http://developer.android.com/guide/components/activities.html#SavingActivityState

Android - Fragment onActivityResult avoid reloading

frammenti possono avere il supporto per onSaveInstanceState ma non onRestoreInstanceState, quindi se si desidera salvare un riferimento alle viste da tavolo, salvarle sul Bundle e si può accedi alla vista salvata nel tuo metodo onActivityCreated. Puoi anche usare lo stack posteriore di Fragments.

This guide/tutorial ha istruzioni/esempi molto dettagliati sullo stack posteriore e sullo stato del frammento di mantenimento.

Buona fortuna

7

Provare a utilizzare fragementTransaction.add invece di sostituire

3

sto postando questa risposta per le persone che possono riferirsi a questa domanda in futuro.

Il seguente codice mostrerà come aprire FragmentB da FragmentA e tornare a FragmentA da FragmentB (senza aggiornare FragmentA) premendo il pulsante Indietro.

public class FragmentA extends Fragment{ 

    ... 

    void openFragmentB(){ 

     FragmentManager fragmentManager = 
      getActivity().getSupportFragmentManager(); 
     FragmentB fragmentB = FragmentB.newInstance(); 

     if (fragmentB.isAdded()) { 

      return; 
     } else { 

      fragmentManager. 
       beginTransaction(). 
       add(R.id.mainContainer,fragmentB). 
       addToBackStack(FragmentB.TAG). 
       commit(); 
     } 
    } 
} 

public class FragmentB extends Fragment{ 

    public static final String TAG = 
     FragmentB.class.getSimpleName(); 

    ... 

    public static FragmentB newInstance(){ 

     FragmentB fragmentB = new FragmentB(); 
     return fragmentB; 
    } 

    @Override 
    public void onResume() { 

     super.onResume(); 
     // add this piece of code in onResume method 
     this.getView().setFocusableInTouchMode(true); 
     this.getView().requestFocus(); 
    } 
} 

Nella tua sostituzione MainActivity onBackPressed()

class MainActivity extends Activity{ 
    ... 

    @Override 
    public void onBackPressed() { 

     if (getFragmentManager().getBackStackEntryCount() > 0) { 

      getFragmentManager().popBackStack(); 
     } else { 

      super.onBackPressed(); 
     } 
    } 
} 
Problemi correlati