从 Android 3.0(API 级别 11)开始,所有使用默认主题的 Activity 均使用 ActionBar 作为应用栏。不过,经过不同 Android 版本的演化,原生 ActionBar 的行为会随 Android 系统的版本而发生变化。相比之下,ActionBar的最新功能已添加到支持库版本的 Toolbar 中,并且这些功能可以在任何能够使用该支持库的设备上使用。
因此,应该使用支持库的 Toolbar 类来实现 Activity 的应用栏。使用支持库的工具栏有助于确保应用在最大范围的设备上保持一致的行为。例如,Toolbar 小部件能够在运行 Android 2.1(API 级别 7)或更高版本的设备上提供 Material Design 体验,但除非设备运行的是 Android 5.0(API 级别 21)或更高版本,否则原生操作栏不会支持 Material Design。
向Activity添加工具栏
向项目添加v7 appcompat 支持库
compile 'com.android.support:appcompat-v7:25.3.1'
Activity扩展AppCompatActivity
在应用清单中,将<application>元素的主题设置为appcompat的其中一个NoActionBar主题。使用这些主题中的一个防止应用使用原生ActionBar类提供应用栏。例如:
<application
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
/>
由于我想改变标题栏中的文字颜色,所以自定义了一个主题继承上例中的主题:
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textColorPrimary">@android:color/white</item>
</style>
<application
android:theme="@style/AppTheme.Base">
向Activity的布局添加一个Toolbar。例如,以下布局代码可以添加一个Toolbar并赋予其浮动在Activity之上的外观:
<android.support.v7.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
在 Activity 的 onCreate() 方法中,调用 Activity 的 setSupportActionBar() 方法,然后传递 Activity 的工具栏。该方法会将工具栏设置为 Activity 的应用栏。例如:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
}
使用应用栏的方法
将工具栏设置为 Activity 的应用栏后,就可以访问 v7 appcompat 支持库的 ActionBar 类提供的各种实用方法。您可以通过此方法执行许多有用的操作,例如隐藏和显示应用栏。
要使用 ActionBar 实用方法,调用 Activity 的 getSupportActionBar() 方法。此方法将返回对 appcompat ActionBar 对象的引用。获得该引用后,就可以调用任何一个 ActionBar 方法来调整应用栏。例如,要隐藏应用栏,请调用 ActionBar.hide()。
修改标题内容
我的MainActivity使用FragmentTabHost来管理三个Fragment。想使每个Fragment对象不同的标题可以在Fragment中修改Title:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mLayout == null) {
mLayout = inflater.inflate(R.layout.fragment_line, container, false);
}
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("线路");
return mLayout;
}
添加操作
添加操作按钮
在res中创建menu文件夹,在menu文件夹中创建menu xml文件line_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/change_line"
android:title="线路"
app:showAsAction="always"/>
</menu>
覆盖Activity的onCreateOptionsMenu方法:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.line_menu, menu);
return true;
}
根据不同的Fragment显示不同的按钮
如上文所述,我的MainActivity使用FragmentTabHost来管理三个Fragment。要想使每个Fragment对应不同的按钮,可以覆盖Activity的onPrepareOptionsMenu方法:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
switch(mTabHost.getCurrentTab()){
case 2 :
menu.findItem(R.id.change_line).setVisible(true);
break;
default:
menu.findItem(R.id.change_line).setVisible(false);
break;
}
return super.onPrepareOptionsMenu(menu);
}
然后给FragmentTabHost设置OnTabChangeListener,调用invalidateOptionsMenu()方法,使Activity重新加载menu,即调用onPrepareOptionsMenu方法:
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
invalidateOptionsMenu();
}
});
设置按钮响应
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
// User chose the "Settings" item, show the app settings UI...
return true;
case R.id.action_favorite:
// User chose the "Favorite" action, mark the current item
// as a favorite...
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}