2012-04-05 11 views
9

Więc używam zakładek i szukając tego rodzaju nawigacji:Jak poruszać się w fragmentach?

Wypustu1 -> wewnątrz 1 -> inside2

TAB2 -> wewnątrz 3 -> wewnątrz 4

tab3 - -> wewnątrz 5

wewnątrz mam na myśli to, że powinien otworzyć nowy układ i klasę.

Mój projekt główny klasa jest taka:

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

} 

to utworzenie 3 karty z tam treści. Oto jak wygląda klasa fragmentów Tab1 (inne wyglądają podobnie):

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

Piszę na przyciskach, co chcę.

Nie mogę otworzyć nowego fragmentu lub aktywności wewnątrz tego fragmentu?

Jak mam nawigować wewnątrz fragmentów?

Odpowiedz

13

Chciałbym, aby mój host Activity obsługiwał wszystkie przejścia, więc to, co robię w swoich fragmentach, to tworzenie interface do obsługi nawigacji. Na przykład, można dodać ten interface do swojej Tab1Fragment:

public interface Callback { 
    public void onButtonBClicked(); 
} 

Następnie w TabsFragmentActivity, wdrożyć Tab1Fragment.Callback, które będą wymagać wdrożenia onButtonBClicked(). Oto przykład sposobu wdrożenia tej metody:

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

Prawie gotowe. Następnie musisz uzyskać odwołanie do tego wywołania zwrotnego w swoim fragmencie. Zwykle osiąga się to w metodzie onAttached(). Na przykład:

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

I wreszcie, w twojej OnClickListener, zadzwoń mCallback.onButtonBClicked().

+0

To jest dobry przykład używania połączeń zwrotnych. Ale jaka jest różnica, jeśli wzywam mój Fragment1 OnClickListiner to: ((TabsFragmentActivity) getActivity()). OnButtonBClicked(); To również wywołałoby onButtonBClicked(). Ale co z obsługą stosów poszczególnych zakładek? – Streetboy

+0

To nie ma znaczenia, z wyjątkiem tego, że jest czystszy, tak jak ja to zrobiłem, ponieważ wystarczy rzucić go raz (jeśli masz lepszy interfejs z wieloma połączeniami). Implementacja, którą mam dla 'onButtonClicked()' dodaje fragment do tylnego stosu, więc ponowne naciśnięcie wyświetli poprzedni fragment. –

+0

OK, jak zmienić karty? Mam na myśli, że idę na tab1 w głęboki stos, a następnie przełączam się na tab2 i tam wchodzę głęboko, a następnie przełączam się ponownie na tab1 i wciskam przycisk Wstecz i chcę, żeby powrócił właśnie w tab1 – Streetboy

Powiązane problemy