本节书摘来自异步社区《Android平板电脑开发秘籍》一书中的第3章,第3.8节技巧:创建一个Tab页式的ActionBar,作者 【印度】B.M. Harwani,更多章节内容可以访问云栖社区“异步社区”公众号查看
3.8 技巧:创建一个Tab页式的ActionBar
Android平板电脑开发秘籍
Tab页式的ActionBar类似于自定义事件处理方法的按钮,它被设计成与Fragment Manager一起使用。为了在ActionBar中显示导航Tab页,请调用setNavigationMode()方法,把值ActionBar.NAVIGATION_MODE_TABS作为参数传入,如下所示:
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
指定了导航模式后,通过调用ActionBar 的addTab()方法可以添加Tab页,如下所示:
actionBar.addTab(actionBar.newTab().setText("Create").setTabListener(this));
以上代码新建了一个Tab页,把它的标题设为“Create”,给它绑定了一个TabListener,最后把新建的Tab页添加到ActionBar中去。例如,这里用setText()方法设置了Tab页的标题。可以调用setIcon()方法来为Tab页定义一个图标。你还可以调用setContentDescription()方法设置Tab页的更多细节信息。
示例:
Tab tab1 = actionBar.newTab();
tabOne.setText("Create")
.setIcon(R.drawable.ic_launcher)
.setContentDescription("Creating the Invoice")
.setTabListener(this));
actionBar.addTab(tab1);
这段代码给ActionBar添加了一个Tab页面,标题为“Create”。与此Tab页关联的图标是默认图标ic_launcher,详细的描述信息是“Creating the Invoice”。当点击Tab页时,事件由TabListener进行处理,完成所需的任务。
现在将通过一个实际的例子来了解Tab页式ActionBar的概念。请创建一个名为的ActionBarTabApp Android项目。在这个应用程序中,将新建两个Tab页:Create和Update。当选中一个Tab页时,对应的Fragment将会被激活,并显示一段文字信息表示该Fragment被激活了。两个Fragment的View将会通过单独的XML Layout文件显示。因此请在res/layout文件夹下分别添加两个名为createfragment.xml和updatefragment.xml的XML文件。
请在createfragment.xml中写入代码清单3-11给出的代码。
代码清单3-11 写入createfragment.xml文件的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/create_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" This is Create Fragment "
android:textSize="@dimen/text_size"
android:textStyle="bold" />
</LinearLayout>
可以看到,上述Layout文件定义了一个TextView,初始时显示文字“This is Create Fragment”。显示此信息即表示第一个Fragment被激活了。类似地,在updatefragment.xml文件中写入代码清单3-12给出的代码。
代码清单3-12 写入updatefragment.xml文件的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/update_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" This is Update Fragment "
android:textSize="@dimen/text_size"
android:textStyle="bold" />
</LinearLayout>
同样,在Layout文件中为第二个Fragemt定义了一个TextView控件。此TextView初始时显示文字“This is Update Fragment”,表示第二个Fragemt被激活了。
为了在选中Action Tab页时能够显示相应Fragemt的内容,需要在Activity Layout文件中定义一个Fragemt容器。因此,在Activity Layout文件activity_action_bar_tab_app.xml中写入代码清单3-13所示的代码。
代码清单3-13 写入Activity Layout文件activity_action_bar_tab_app.xml的代码
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/fragment_container"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
为了载入两个Fragment的View,请在Android项目的包com.androidtablet.action bartabapp中添加两个Java类文件:CreateActivity.java和UpdateActivity.java。
为了从Layout文件createfragment.xml中载入View,请把代码清单3-14给出的代码写入CreateActivity.java文件。
代码清单3-14 写入CreateActivity.java文件的代码
package com.androidtablet.actionbartabapp;
import android.app.Fragment;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.os.Bundle;
public class CreateActivity extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.createfragment,
container, false);
}
}
同样,为了从Layout文件updatefragment.xml载入View,请把代码清单3-15给出的代码写入UpdateActivity.java文件。
代码清单3-15 写入UpdateActivity.java文件的代码
package com.androidtablet.actionbartabapp;
import android.app.Fragment;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.os.Bundle;
public class UpdateActivity extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.updatefragment, container, false);
}
}
接下来,需要在主Activity文件ActionBarTabAppActivity.java中写入一些Java代码,以完成以下任务。
在应用程序中定义两个Tab页:Create和Update。
定义Tab页侦听器并与两个Tab页关联。
当相应的Tab页被点击时,激活Fragment Create和Update。
为了完成上述所有任务,把代码清单3-16所给出的代码写入Java Activity文件ActionBarTab AppActivity.java中。
代码清单3-16 写入Java Activity文件ActionBarTabAppActivity.java的代码
package com.androidtablet.actionbartabapp;
import android.os.Bundle;
import android.app.Activity;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.util.Log;
import android.app.FragmentManager;
import android.app.Fragment;
public class ActionBarTabAppActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_action_bar_tab_app);
Fragment createFragment = new CreateActivity();
Fragment updateFragment = new UpdateActivity();
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_
MODE_TABS);
actionBar.setDisplayShowTitleEnabled(true);
ActionBar.Tab CreateTab = actionBar.newTab().
setText("Create");
ActionBar.Tab UpdateTab = actionBar.newTab().
setText("Update");
CreateTab.setTabListener(new MyTabsListener(
createFragment));
UpdateTab.setTabListener(new MyTabsListener(updateFragment));
actionBar.addTab(CreateTab);
actionBar.addTab(UpdateTab);
}
protected class MyTabsListener implements ActionBar.
TabListener {
Fragment fragment;
public MyTabsListener(Fragment fragment){
this.fragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.fragment_container, fragment, null);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
getFragmentManager().popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Log.d("Tab", String.valueOf(tab.getPosition()) +
" re-selected");
}
}
}
可以看到,调用getActionBar()方法创建了ActionBar对象。为了让ActionBar以 Tab页的方式显示,把它的导航模式设成了ActionBar.NAVIGATION_MODE_TABS。可以在setDisplayShowTitleEnabled()方法传入布尔值False,来隐藏Activity的标题。然后,创建两个标签为Create和Update的Tab页,并添加到ActionBar中。
事件侦听器TabListener与两个Tab页都关联。不管选中哪一个Tab页,onTabSelected()方法都会被调用,并打开预设的Fragment。onTabSelected()方法激活相应的Fragment,把定义于Layout文件的View显示出来。当Tab页被选中时,onTabUnselected ()方法也会被调用,那些没有被选中的Tab页将作为参数传入。与未选中Tab页关联的Fragment将会从堆栈中移除,这些Fragment变为不可见。
onTabUnselected ()方法将显示未选中Tab页的位置1。运行此应用程序后,你将看到Tab页式ActionBar显示了两个Tab页:Create和Update。当你选择Create页后,与之相关联的Fragment将会被激活,显示出一条信息“This is Create Fragment”,如图3-8上所示。类似地,在选择Update页后,与之关联的Fragment将会被激活,显示出文字信息“This is Update Fragment”,如图3-8下所示。