2012-04-05 13 views
9

So bin ich mit Tabs und für diese Art von Navigation sucht:Wie navigiere ich in Fragmenten?

tab1 -> innerhalb 1 -> inside2

tab2 -> innerhalb 3 -> innen 4

tab3 - -> innerhalb 5

innerhalb ich meine, dass es ein neues Layout und eine neue Klasse öffnen sollte.

Mein Projekt Hauptklasse ist dies:

public class TabsFragmentActivity extends SherlockFragmentActivity implements 
     TabHost.OnTabChangeListener { 

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

    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); 

     // Step 1: Inflate layout 
     setContentView(R.layout.tabs_fragment_activity); 

     mContext = this; 

     // Step 2: Setup TabHost 
     initialiseTabHost(savedInstanceState); 

     if (savedInstanceState != null) { 
      mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); 
     } 

     addNavaigationBar(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     //Add Action item with title 
      menu.add("some") 
      .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); 

     return super.onCreateOptionsMenu(menu); 
    } 

    public void addNavaigationBar() { 
     // Create Action Bar sherlock 
     ActionBar navigation_bar = getSupportActionBar(); 

     // Setting standart navigation bar view 
     navigation_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 

     navigation_bar.setDisplayShowTitleEnabled(true); 
     navigation_bar.setTitle("Test"); 

     // Override Action items to navigation bar. Calls onCreateOptionsMenu 
     // invalidateOptionsMenu(); 
    } 

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

    /** 
    * Step 2: Setup TabHost 
    */ 
    private void initialiseTabHost(Bundle args) { 
     mTabHost = (TabHost) findViewById(android.R.id.tabhost); 

     mTabHost.setup(); 

     TabInfo tabInfo = null; 

     TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost 
       .newTabSpec("Tab1").setIndicator("Tab 1"), 
       (tabInfo = new TabInfo("Tab1", Tab1Fragment.class, args))); 

     this.mapTabInfo.put(tabInfo.tag, tabInfo); 


     TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost 
       .newTabSpec("Tab2").setIndicator("Tab 2"), 
       (tabInfo = new TabInfo("Tab2", Tab2Fragment.class, args))); 

     this.mapTabInfo.put(tabInfo.tag, tabInfo); 

     TabsFragmentActivity.addTab(this, this.mTabHost, this.mTabHost 
       .newTabSpec("Tab3").setIndicator("Tab 3"), 
       (tabInfo = new TabInfo("Tab3", Tab3Fragment.class, args))); 

     this.mapTabInfo.put(tabInfo.tag, tabInfo); 
     // Default to first tab 
     this.onTabChanged("Tab1"); 
     // 
     mTabHost.setOnTabChangedListener(this); 
    } 

    private static void addTab(TabsFragmentActivity 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(); 
     //getTabWidget() 

     View view = prepareTabView(activity, R.id.tab_bar_icon); 
     tabSpec.setIndicator(view); 

     // 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); 
    } 

    private static View prepareTabView(Context context, int drawable){ 
     //inflate(R.layout.tab_indicator, android.R.id.tabs, false) 
     View tabIndicator = LayoutInflater.from(context).inflate(R.layout.tab_indicator, null); 
     ImageView icon = (ImageView) tabIndicator.findViewById(R.id.tab_bar_icon); 
     icon.setImageResource(R.drawable.ic_launcher); 
     return tabIndicator; 

    } 

    public void onTabChanged(String tag) { 
     TabInfo newTab = this.mapTabInfo.get(tag); 

     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(); 
     } 
    } 

} 

Dieses 3 Tabs mit dort Inhalt erstellen. Hier sehen Sie wie Tab1 Fragment-Klasse (andere ähnlich aussehen):

public class Tab1Fragment extends SherlockFragment { 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     if (container == null) { 
      // We have different layouts, and in one of them this 
      // fragment's containing frame doesn't exist. The fragment 
      // may still be created from its saved state, but there is 
      // no reason to try to create its view hierarchy because it 
      // won't be displayed. Note this is not needed -- we could 
      // just run the code below, where we would create and return 
      // the view hierarchy; it would just never be used. 
      return null; 
     } 
     LinearLayout theLayout = (LinearLayout)inflater.inflate(R.layout.tab_frag1_layout, container, false); 
     // Register for the Button.OnClick event 
     Button b = (Button)theLayout.findViewById(R.id.frag1_button); 
     b.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

**//Here i want open a new window but don't change pressed tab and when press back it should go back at this window** 
      } 
     }); 
     return theLayout; 
    } 
} 

Ich schreibe auf Knopfdruck was ich will.

Ich kann ein neues Fragment oder eine neue Aktivität in diesem Fragment nicht öffnen?

Wie sollte ich Navigation in Fragmenten tun?

Antwort

13

Ich mag meinen Host Activity behandeln alle Übergänge, also was ich in meinen Fragmenten tun, ist ein interface zu schaffen, um Navigation zu handhaben.

public interface Callback { 
    public void onButtonBClicked(); 
} 

Dann in Ihrem TabsFragmentActivity, implementieren Tab1Fragment.Callback, die Sie benötigen, onButtonBClicked() zu implementieren: Zum Beispiel könnten Sie diese interface zu Ihrem Tab1Fragment hinzuzufügen. Hier ist ein Beispiel dafür, wie Sie diese Methode implementieren können:

@Override 
public void onButtonBClicked() { 

    Fragment anotherFragment = Fragment.instantiate(this, AnotherFragment.class.getName()); 
    FragmentTransaction ft = getFragmentManager().beginTransaction(); 
    ft.add(R.id.realtabcontent, anotherFragment); 
    ft.addToBackStack(null); 
    ft.commit(); 
} 

Fast fertig. Als nächstes müssen Sie einen Verweis auf diesen Callback in Ihrem Fragment erhalten. Dies wird typischerweise in der onAttached() Methode erreicht. Zum Beispiel:

@Override 
public void onAttach(Activity activity) { 

    super.onAttach(activity); 
    try { 
     mCallback = (Callback) activity; 
    } 
    catch (ClassCastException e) { 
     throw new ClassCastException(activity.toString() + " must implement " + Callback.class.getName()); 
    } 
} 

Und schließlich in Ihrem OnClickListener, rufen mCallback.onButtonBClicked().

+0

Dies ist ein gutes Beispiel für die Verwendung von Rückrufen. Aber was ist der Unterschied, wenn ich in meinem Fragment1 OnClickListiner dies anrufe: ((TabsFragmentActivity) getActivity()). OnButtonBClicked(); Dies würde auch onButtonBClicked() aufrufen. Aber was ist mit der Handhabung von Stapeln jeder Registerkarte? – Streetboy

+0

Es macht keinen Unterschied, außer es ist sauberer, wie ich es getan habe, da Sie es nur einmal werfen müssten (wenn Sie eine stärkere Schnittstelle mit mehreren Anrufen hatten). Die Implementierung, die ich für 'onButtonClicked()' habe, fügt das Fragment dem Backstack hinzu, so dass das Zurückdrücken das vorherige Fragment anzeigt. –

+0

Ok, dann, wie Tabs zu wechseln? Ich meine, ich gehe Tab1 in den Deep Stack, dann wechsle zu Tab2 und gehe dort in Deep und wechsle dann wieder zu Tab1 und drücke den Zurück Button und ich möchte dass es nur in tab1 zurückgeht. – Streetboy

Verwandte Themen