2012-04-05 34 views
9

所以我使用的标签,寻求这种导航:如何在碎片中导航?

TAB1 - >内1 - > inside2

TAB2 - >内3 - >内4

TAB3 - - >里面5

里面我的意思是它应该打开一个新的布局和类。

我的项目主类是这样的:

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

} 

此创建3个标签与内容存在。这是怎么看待TAB1片段类(其他外观相似):

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

我写的按钮按我想要的东西。

我无法在此片段内打开新的片段或活动?

我应该如何在碎片中进行导航?

回答

13

我喜欢让我的主机Activity处理所有的转换,所以我在我的片段中做的是创建一个interface来处理导航。在TabsFragmentActivity

public interface Callback { 
    public void onButtonBClicked(); 
} 

然后,实施Tab1Fragment.Callback,这将需要你实现onButtonBClicked():例如,你可以添加这个interfaceTab1Fragment。下面是如何实现此方法的示例:

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

几乎完成。接下来,您需要做的是在您的片段中获取对此回调的引用。这通常在onAttached()方法中实现。例如:

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

最后,在你的OnClickListener,叫mCallback.onButtonBClicked()

+0

这是使用回调的好例子。但是,如果我打电话给我的Fragment1 OnClickListiner,这有什么区别: ((TabsFragmentActivity)getActivity())。onButtonBClicked(); 这也可以调用onButtonBClicked()。但是如何处理每个标签的堆栈呢? – Streetboy 2012-04-18 05:38:13

+0

它没有什么区别,除了它更清洁,我已经做了,因为你只需要投一次(如果你有多个调用的更强大的接口)。我为'onButtonClicked()'实现的实现将片段添加到后退堆栈,所以后退将显示前一个片段。 – 2012-04-18 15:27:37

+0

好吧然后如何切换标签?我的意思是我把tab1放到深栈中,然后切换到tab2,然后进入深层,然后再切换到tab1,然后按回来按钮,我希望它会返回到tab1 – Streetboy 2012-04-19 06:10:26