2012-06-12 10 views
14

Ho lavorato con Android per un po ', ma i frammenti sono un po' nuovi per me (come lo sono per la maggior parte delle persone probabilmente). Ad ogni modo, ho il codice qui sotto, e funziona perfettamente. Ho tre frammenti, uno in ogni scheda. Mi chiedo se è normale che onCreateView venga chiamato ogni volta che cambio scheda, e ha senso farlo? Non dovrebbe esserci un modo per NON ridisegnare il frammento ogni volta che la scheda cambia?frammento Android oncreateview chiamato su cambio scheda

Sto convertendo questo da un'applicazione che ha 3 attività, una in ogni scheda, e mi sembra uno spreco ricreare la vista ogni volta che la scheda cambia, quando una volta andava bene avendo le viste esistenti tra scheda cambia ...

BTW, questo codice preso in prestito da: http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/

public class Tabs extends FragmentActivity implements 
    TabHost.OnTabChangeListener { 

final String MAP_TAB = "Map"; 
final String IMAGES_TAB = "Images"; 
final String SETTINGS_TAB = "Settings"; 

TabHost mTabHost; 
HashMap<String, TabInfo> mapTabInfo = new HashMap<String, TabInfo>(); 
TabInfo mLastTab = null; 

private class TabInfo { 
    private String tag; 
    private Class clss; 
    private Bundle args; 
    private Fragment fragment; 
    TabInfo(String tag, Class clazz, Bundle args) { 
     this.tag = tag; 
     this.clss = clazz; 
     this.args = args; 
    } 

} 

class TabFactory implements TabContentFactory { 

    private final Context mContext; 

    public TabFactory(Context context) { 
     mContext = context; 
    } 

    public View createTabContent(String tag) { 
     View v = new View(mContext); 
     v.setMinimumWidth(0); 
     v.setMinimumHeight(0); 
     return v; 
    } 

} 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.main); 

    initialiseTabHost(savedInstanceState); 
    if (savedInstanceState != null) 
     mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state 
} 

protected void onSaveInstanceState(Bundle outState) { 
    outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected 
    super.onSaveInstanceState(outState); 
} 

private void initialiseTabHost(Bundle args) { 
    mTabHost = (TabHost)findViewById(android.R.id.tabhost); 
    mTabHost.setup(); 
    TabInfo tabInfo; 

    Tabs.addTab(this, 
      mTabHost, 
      mTabHost.newTabSpec(MAP_TAB).setIndicator(
        MAP_TAB, 
        getResources().getDrawable(R.drawable.ic_tab_map_states)), 
      (tabInfo = new TabInfo(MAP_TAB, HMapFragment_NEW.class, args))); 
    mapTabInfo.put(tabInfo.tag, tabInfo); 

    Tabs.addTab(this, 
      mTabHost, 
      mTabHost.newTabSpec(IMAGES_TAB).setIndicator(
        IMAGES_TAB, 
        getResources().getDrawable(R.drawable.ic_tab_gallery_states)), 
      (tabInfo = new TabInfo(IMAGES_TAB, ImageGridFragment.class, args))); 
    mapTabInfo.put(tabInfo.tag, tabInfo); 

    Tabs.addTab(this, 
      mTabHost, 
      mTabHost.newTabSpec(SETTINGS_TAB).setIndicator(
        SETTINGS_TAB, 
        getResources().getDrawable(R.drawable.ic_tab_settings_states)), 
      (tabInfo = new TabInfo(SETTINGS_TAB, SettingsFragment.class, args))); 
    mapTabInfo.put(tabInfo.tag, tabInfo); 

    // Default to first tab 
    this.onTabChanged(MAP_TAB); 
    mTabHost.setOnTabChangedListener(this); 
} 

private static void addTab(Tabs activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) { 
    // Attach a Tab view factory to the spec 
    tabSpec.setContent(activity.new TabFactory(activity)); 
    String tag = tabSpec.getTag(); 

    // Check to see if we already have a fragment for this tab, probably 
    // from a previously saved state. If so, deactivate it, because our 
    // initial state is that a tab isn't shown. 
    tabInfo.fragment = activity.getSupportFragmentManager().findFragmentByTag(tag); 
    if (tabInfo.fragment != null && !tabInfo.fragment.isDetached()) { 
     FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 
     ft.detach(tabInfo.fragment); 
     ft.commit(); 
     activity.getSupportFragmentManager().executePendingTransactions(); 
    } 

    tabHost.addTab(tabSpec); 
} 

public void onTabChanged(String tag) { 
    TabInfo newTab = this.mapTabInfo.get(tag); 
    // if they've clicked to change tabs 
    if (mLastTab != newTab) { 
     FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction(); 
     if (mLastTab != null) 
      if (mLastTab.fragment != null) ft.detach(mLastTab.fragment); 
     if (newTab != null) { 
      if (newTab.fragment == null) { 
       newTab.fragment = Fragment.instantiate(this, newTab.clss.getName(), newTab.args); 
       ft.add(R.id.realtabcontent, newTab.fragment, newTab.tag); 
      } else ft.attach(newTab.fragment); 
     } 

     mLastTab = newTab; 
     ft.commit(); 
     this.getSupportFragmentManager().executePendingTransactions(); 
    } 
} 
} 

risposta

24

Esiste un 3 modi per rimuovere un frammento di vista:

  • nasconderlo (hide funzione oggetto di transazione)
  • staccarlo (detach funzione oggetto di transazione)
  • rimuoverlo (remove funzione oggetto di transazione)

Se nascondere che la vista viene nascosta, ma è ancora nel layout e dovrebbe rimanere intatto. Se si sostituisce , la vista viene eliminata, ma il frammento viene comunque gestito da FragmentManager (e verrà ricreato in una modifica della configurazione, ad esempio). Se si rimuovere esso viene rimosso completamente da FragmentManager e lo stato non sarà più gestito.

+0

quindi forse dovrei provare a cambiare la chiamata di stacco sopra per nascondere? – Josh

+0

sì, che dovrebbe fare il trucco –

+0

ovviamente anche bisogno di cambiare attaccare per aggiungere, ma esattamente quello che volevo! Grazie! Esattamente perché uso SO haha ​​ – Josh

Problemi correlati