在ApiDemos工程的FragmentTabs类中,展示如何将ActionBar变成Tab形式,并将tab内容绑定到一个Fragment。
1. 将ActionBar设置成标签模式
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
2. 添加标签页,并设置事件监听
bar.addTab(bar.newTab()
.setText("Simple")
.setTabListener(new TabListener<FragmentStack.CountingFragment>(
this, "simple", FragmentStack.CountingFragment.class)));
bar.addTab(bar.newTab()
.setText("Contacts")
.setTabListener(new TabListener<LoaderCursor.CursorLoaderListFragment>(
this, "contacts", LoaderCursor.CursorLoaderListFragment.class)));
bar.addTab(bar.newTab()
.setText("Apps")
.setTabListener(new TabListener<LoaderCustom.AppListFragment>(
this, "apps", LoaderCustom.AppListFragment.class)));
bar.addTab(bar.newTab()
.setText("Throttle")
.setTabListener(new TabListener<LoaderThrottle.ThrottledLoaderListFragment>(
this, "throttle", LoaderThrottle.ThrottledLoaderListFragment.class)));
调用ActionBar的接口addTab()就可以向ActionBar添加标签,标签的标题是通过setText来设置的,另外需要设置TabListener,它的实现形式如下:
public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener(Activity activity, String tag, Class<T> clz) {
this(activity, tag, clz, null);
}
public TabListener(Activity activity, String tag, Class<T> clz, Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
// 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.
mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
ft.detach(mFragment);
ft.commit();
}
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT).show();
}
}
上面主要有3个回调需要实现,分别如下:
public void onTabSelected(Tab tab, FragmentTransaction ft)
public void onTabUnselected(Tab tab, FragmentTransaction ft)
public void onTabUnselected(Tab tab, FragmentTransaction ft)
这些回调的用法可以顾名思义,非常简单。其中比较主要的是处理Fragment的逻辑,在onTabSelected的时候,如果当前绑定的Fragment还没有被创建,那么我们就会创建一个新的Fragment,并且添加到android.R.id.content,当然你也可以添加到别的View中。如果已经存在了,那么只需调用ft的attach函数即可。
当标签页不被选择的时候,只需要调用ft.detach即可,这样这个Fragment只需要重建UI,而无须destroy,这样可以确保一定的效率。
运行实例效果如下: