2012-06-12 7 views
14

He estado trabajando con Android por un tiempo, pero los fragmentos son un poco nuevos para mí (como lo son para la mayoría de la gente, probablemente). De todos modos, tengo el siguiente código, y funciona bien. Tengo tres fragmentos, uno en cada pestaña. Me pregunto si es normal que se llame a onCreateView cada vez que cambio de pestaña, ¿y tiene sentido hacerlo? ¿No debería haber una forma de NO volver a dibujar el fragmento cada vez que cambia la pestaña?Android fragmento oncreateview llamado en cambio de pestaña

Estoy convirtiendo esto de una aplicación que tenía 3 actividades, una en cada pestaña, y parece una pérdida para volver a crear la vista cada vez que la pestaña cambia, cuando solía estar bien tener las vistas existentes entre pestaña cambios ...

Por cierto, este código prestado de: 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(); 
    } 
} 
} 

Respuesta

24

allí unas 3 formas para eliminar un fragmento de la vista:

  • ocultarla (hide función de objeto de transacción)
  • separarla (detach función de objeto de transacción)
  • retirarla (remove función de objeto de transacción)

Si ocultar que la vista se oculta, pero sigue siendo en el diseño y debe permanecer intacto. Si se separa, la vista se derriba, pero el fragmento sigue siendo gestionado por el FragmentManager (y se volverá a crear en un cambio de configuración, por ejemplo). Si elimina, se eliminará por completo de FragmentManager y su estado ya no se gestionará.

+0

así que tal vez debería intentar cambiar la llamada de desconexión anterior para ocultarla? – Josh

+0

sí, eso debería hacer el truco –

+0

obviamente también necesitaba cambiar adjuntar para agregar, ¡pero exactamente lo que quería! ¡Gracias! Exactamente por qué uso SO haha ​​ – Josh

Cuestiones relacionadas