This interface is deprecated.
Action bar navigation modes are deprecated and not supported by inline toolbar action bars. Consider using other common navigation patterns instead.
Adding Navigation Tabs
Figure 7. Action bar tabs on a wide screen.
Tabs in the action bar make it easy for users to explore and switch between different views in your app. The tabs provided by the ActionBar
are ideal because they adapt to different screen sizes. For example, when the screen is wide enough the tabs appear in the action bar alongside the action buttons (such as when on a tablet, shown in figure 7), while when on a narrow screen they appear in a separate bar (known as the "stacked action bar", shown in figure 8). In some cases, the Android system will instead show your tab items as a drop-down list to ensure the best fit in the action bar.
Figure 8. Tabs on a narrow screen.
Tab模式并不一定显示为图8那样,要看屏幕大小,够大时显示如图7,有些情况还可能显示为下拉列表
To get started, your layout must include a ViewGroup
in which you place each Fragment
associated with a tab. Be sure the ViewGroup
has a resource ID so you can reference it from your code and swap the tabs within it. Alternatively, if the tab content will fill the activity layout, then your activity doesn't need a layout at all (you don't even need to call setContentView()
). Instead, you can place each fragment in the default root view, which you can refer to with the android.R.id.content
ID.
如果每个tab对应的fragment都是填满宿主activity的,那么宿主activity可以不用有layout文件,不用setContentView(),可以让fragment寄生在default root view上,它的id是android.R.id.content
Once you determine where the fragments appear in the layout, the basic procedure to add tabs is:
开启顶部tab模式的步骤如下:
- Implement the
ActionBar.TabListener
interface. This interface provides callbacks for tab events, such as when the user presses one so you can swap the tabs.实现tab接口
- For each tab you want to add, instantiate an
ActionBar.Tab
and set theActionBar.TabListener
by callingsetTabListener()
. Also set the tab's title and withsetText()
(and optionally, an icon withsetIcon()
).构造一个ActionBar.Tab类,设置tab接口,标题,图标.
- Then add each tab to the action bar by calling
addTab()
.调用actionBar.addTab();
Notice that the ActionBar.TabListener
callback methods don't specify which fragment is associated with the tab, but merely which ActionBar.Tab
was selected. You must define your own association between each ActionBar.Tab
and the appropriate Fragment
that it represents. There are several ways you can define the association, depending on your design.
For example, here's how you might implement the ActionBar.TabListener
such that each tab uses its own instance of the listener:
public static class TabListener<T extends Fragment> implements ActionBar.TabListener { private Fragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; /** Constructor used each time a new tab is created. * @param activity The host Activity, used to instantiate the fragment * @param tag The identifier tag for the fragment * @param clz The fragment's Class, used to instantiate the fragment */ public TabListener(Activity activity, String tag, Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; } /* The following are each of the ActionBar.TabListener callbacks */ public void onTabSelected(Tab tab, FragmentTransaction ft) { // Check if the fragment is already initialized if (mFragment == null) { // If not, instantiate and add it to the activity mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } else { // If it exists, simply attach it in order to show it ft.attach(mFragment); } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (mFragment != null) { // Detach the fragment, because another one is being attached ft.detach(mFragment); } } public void onTabReselected(Tab tab, FragmentTransaction ft) { // User selected the already selected tab. Usually do nothing. } }
Caution: You must not call commit()
for the fragment transaction in each of these callbacks—the system calls it for you and it may throw an exception if you call it yourself. You also cannot add these fragment transactions to the back stack.
注意在ActionBar.TabListener的回调函数中有个FragmentTransaction ft ,不能调用它的commit函数,否则出异常,系统会帮你调用.
In this example, the listener simply attaches (attach()
) a fragment to the activity layout—or if not instantiated, creates the fragment and adds (add()
) it to the layout (as a child of the android.R.id.content
view group)—when the respective tab is selected, and detaches (detach()
) it when the tab is unselected.
All that remains is to create each ActionBar.Tab
and add it to the ActionBar
. Additionally, you must call setNavigationMode(NAVIGATION_MODE_TABS)
to make the tabs visible.
For example, the following code adds two tabs using the listener defined above:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Notice that setContentView() is not used, because we use the root // android.R.id.content as the container for each fragment // setup action bar for tabs ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(false); Tab tab = actionBar.newTab() .setText(R.string.artist) .setTabListener(new TabListener<ArtistFragment>( this, "artist", ArtistFragment.class)); actionBar.addTab(tab); tab = actionBar.newTab() .setText(R.string.album) .setTabListener(new TabListener<AlbumFragment>( this, "album", AlbumFragment.class)); actionBar.addTab(tab); }
If your activity stops, you should retain the currently selected tab with the saved instance state so you can open the appropriate tab when the user returns. When it's time to save the state, you can query the currently selected tab with getSelectedNavigationIndex()
. This returns the index position of the selected tab.
注意要保存tab对应的fragment的状态.getSelectedNavigationIndex()可以得到被选中的tab的index
Caution: It's important that you save the state of each fragment so when users switch fragments with the tabs and then return to a previous fragment, it looks the way it did when they left. Some of the state is saved by default, but you may need to manually save state for customized views. For information about saving the state of your fragment, see the Fragments API guide.
Note: The above implementation for ActionBar.TabListener
is one of several possible techniques. Another popular option is to use ViewPager
to manage the fragments so users can also use a swipe gesture to switch tabs. In this case, you simply tell the ViewPager
the current tab position in the onTabSelected()
callback. For more information, read Creating Swipe Views with Tabs.