Android经典应用程序开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.5 菜单、对话框和标题栏

ContentView是一个Activity中的主要内容,菜单、对话框和标题栏是一个Activity中几个附属的部分。

2.5.1 菜单的使用

菜单是屏幕中比较独立的一个元素,在Android中,菜单不同于一个普通的控件,其有单独的接口和运作方式。

在Android中具有单独接口,负责建立活动中的菜单(通常位于下部),主要菜单是用于活动中,这种属于活动的菜单为OptionsMenu(选项菜单)。

使用选项菜单主要通过重载Activity中的几个方法来实现:

        public boolean onCreateOptionsMenu(Menu menu)
        public boolean onOptionsItemSelected(MenuItem item)
        public void onOptionsMenuClosed (Menu menu)

onCreateOptionsMenu()用于在建立菜单时进行设置,建立时为每一个按钮设置ID,菜单项被选择时调用onOptionsItemSelected(),通过MenuItem类的getItemId()方法获得这个菜单的ID,继续进行处理。onOptionsMenuClosed()用于一个菜单启动后被取消时的处理。

另外一种菜单属于某个View,这种菜单称为ContextMenu(上下文菜单),上下文菜单使用如下的方法来构建。

        public void onCreateContextMenu (ContextMenu menu, View v,
                                    ContextMenu.ContextMenuInfo menuInfo)
        public boolean onContextItemSelected(MenuItem item)
        public void  onContextMenuClosed(Menu menu)

菜单的几个相关类均在android.view包中:Menu接口表示选项菜单,ContextMenu表示上下文菜单,MenuItem接口表示一个菜单项目。

提示:Activity中的onCreateContextMenu是View.OnCreateContextMenuListener接口中的方法,Activity实现了这个接口。由于Activity类实现了这个接口,因此在Activity中实现上下文菜单不需要再继承这个接口,直接实现其中的方法即可。

1.基本菜单使用

对于一些比较简单的菜单,可以通过直接操作Menu接口来完成,Menu主要具有以下一些方法:

        public abstract MenuItem add(int groupId, int itemId, int order, CharSequence title)
        public abstract MenuItem add(int groupId, int itemId, int order, int titleRes)

add()的第1、2个参数是整数值,分别代表按钮项的组ID和菜单ID,第3个参数用于设置按钮上的文件。itemId是菜单的主要标识。

MenuItem也是一个接口,其中主要包含了如下的方法:

        public abstract MenuItem setTitle (CharSequence title)    // 设置标题
        public abstract MenuItem setTitle (int title)             // 设置标题
        public abstract MenuItem setIcon (int iconRes)            // 设置图标
        public abstract MenuItem setIntent (Intent intent)        // 设置事件
        public abstract MenuItem setVisible (boolean visible)     // 设置可见性

根据Menu返回MenuItem的句柄之后,除了可以设置标题之外,还可以设置图标、菜单的事件、可见性等内容。

ContextMenu是Menu接口的一个实现者,用于表示上下文菜单。它比Menu多了几个方法,如下所示:

        public abstract ContextMenu setHeaderTitle (CharSequence title)    // 设置标题
        public abstract ContextMenu setHeaderTitle (int titleRes)          // 设置标题
        public abstract ContextMenu setHeaderIcon (int iconRes)            // 设置图标

上下文菜单和选项菜单的主要区别在于它多出了一个标题栏,因此可以设置标题栏和标题和图标。

以下的例程序使用选项菜单和上下文菜单来控制按钮的背景颜色和文本。程序的运行效果如图2-11所示。

图2-11 菜单示例程序的运行结果(左:原始程序;中:选项菜单;右:上下文菜单)

程序运行后,单击菜单按钮将出现选项菜单,在按钮中长按将出现上下文菜单,两种菜单分别如图2-11中的中图和右图所示。

在选项菜单方面,主要的内容是建立和选择两个部分,这段代码如下所示:

            public static final int RED_MENU_ID   = Menu.FIRST;
            public static final int GREEN_MENU_ID = Menu.FIRST + 1;
            public static final int BLUE_MENU_ID  = Menu.FIRST + 2;
            @Override
            public boolean onCreateOptionsMenu(Menu menu) {   // 创建选项菜单
              super.onCreateOptionsMenu(menu);
              menu.add(0, RED_MENU_ID, 0, R.string.red);     // 增加菜单项
              menu.add(0, GREEN_MENU_ID, 0, R.string.green);
              menu.add(0, BLUE_MENU_ID, 0, R.string.blue);
              return true;
            }
            @Override
            public boolean onOptionsItemSelected(MenuItem item) { // 创建菜单项目被选择
              switch (item.getItemId()) {                         // 获得菜单的ID
              case RED_MENU_ID:
                  mButton.setBackgroundColor(Color.RED);          // 设置红色
                  mButton.setText(R.string.red);
                  return true;
              case GREEN_MENU_ID:
                  mButton.setBackgroundColor(Color.GREEN);        // 设置绿色
                  mButton.setText(R.string.green);
                  return true;
              case BLUE_MENU_ID:
                  mButton.setBackgroundColor(Color.BLUE);         // 设置蓝色
                  mButton.setText(R.string.blue);
                  return true;
              }
              return super.onOptionsItemSelected(item);          // 调用默认的处理
            }
        }

onCreateOptionsMenu()创建菜单的内容,onOptionsItemSelected()响应每一个菜单项目的内容。MenuItem中的getItemId()方法用于标识是哪一个菜单发生了事件,返回的数值和建立菜单时候的itemId数值含义相同。

在上下文菜单方面,主要的内容也是建立和选择两个部分,这段代码如下所示:

        public static final int CYAN_MENU_ID   = Menu.FIRST + 10; // 上下文菜单的id
        public static final int YELLOW_MENU_ID = Menu.FIRST + 11;
        public static final int MAGENTA_MENU_ID  = Menu.FIRST + 12;
        @Override
        public void onCreateContextMenu(ContextMenu menu, View view,
                                          ContextMenuInfo menuInfo) {
            menu.setHeaderTitle(R.string.color);                   // 设置上下文菜单的标题栏
            menu.add(0, CYAN_MENU_ID, 0, R.string.cyan);
            menu.add(0, YELLOW_MENU_ID, 0, R.string.yellow);
            menu.add(0, MAGENTA_MENU_ID, 0, R.string.magenta);
        }
        @Override
        public boolean onContextItemSelected(MenuItem item) {
            mButton.setText(item.getTitle());                      // 创建上下文菜单的标题
            switch (item.getItemId()) {
            case CYAN_MENU_ID:
              mButton.setBackgroundColor(Color.CYAN);              // 设置青色
              return true;
            case YELLOW_MENU_ID:
              mButton.setBackgroundColor(Color.YELLOW);            // 设置黄色
              return true;
            case MAGENTA_MENU_ID:
              mButton.setBackgroundColor(Color.MAGENTA);           // 设置洋红色
              return true;
            }
            return false;
        }

在Activity中的onCreate()中使用以下代码,将创建上下文菜单的接口设置给某个控件,代码如下所示:

        mButton = (Button) findViewById(R.id.color_button);
        mButton.setOnCreateContextMenuListener(this);//实现了OnCreateContextMenuListener

onCreateContextMenu()的参数中,具有一个View的句柄,根据这个信息,可以选择为不同的控件建立不同的菜单。

2.从XML文件中生成菜单

由于各个菜单的项目具有很大的通用性,因此Android提供了使用XML文件来描述菜单的方法。菜单的描述文件通常可以用放置在res/menu中的XML文件表示。

android.view中的MenuInflater类可以用于将XML文件描述的菜单转化成菜单对象,MenuInflater主要包含一个inflate()方法,如下所示:

        public void inflate (int menuRes, Menu menu)

inflate()的第2个参数是Menu,表示将XML文件表示的菜单内容增加到这个菜单类当中。

ApiDemo中的Inflate from XML程序从XML文件中建立菜单:

        Inflate from XML(ApiDemo =>App=>Menu=>Inflate from XML)

源文件:src/com/example/android/apis/app/MenuInflateFromXml.java

菜单文件:res/menu/*

Inflate from XML程序的运行效果如图2-12所示。

本程序的菜单中,使用各个XML文件来描述,其中res/menu中的title_only.xml是一个基本菜单的描述,内容如下所示:

        <menu xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:id="@+id/jump"   android:title="@string/jump" />
            <item android:id="@+id/dive"   android:title="@string/dive" />
        </menu>

其中android:id表示菜单的id,而android:title表示菜单上显示的文本。

图2-12 使用XML文件生成菜单运行效果(左:只有标题;中:设置;右:带有图标的菜单)

另一个描述菜单的XML文件title_icon.xml如下所示:

        <menu xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:id="@+id/happy"       android:title="Happy"
              android:icon="@drawable/stat_happy" />
            <item android:id="@+id/neutral"     android:title="Neutral"
              android:icon="@drawable/stat_neutral" />
            <item android:id="@+id/sad"          android:title="Sad"
              android:icon="@drawable/stat_sad" />
        </menu>

android:icon表示一个菜单上的图标,这里将其指向几张图片文件。

在对应的Java代码中,需要在onCreateOptionsMenu()中使用MenuInflater对菜单的XML文件进行处理,内容如下所示:

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            mMenu = menu;
            MenuInflater inflater = getMenuInflater();// 获得MenuInflater
            inflater.inflate                           //第一个参数菜单的资源id,第二个参数Menu
                    (sMenuExampleResources[mSpinner.getSelectedItemPosition()], menu);
            // ......省略部分内容
            return true;
        }

onOptionsItemSelected()的处理过程和不使用XML文件的方法相同。只是其中MenuItem的id来自于XML文件中的定义。

2.5.2 对话框的使用

在GUI程序中,有时需要弹出对话框来提示一些信息。这些对话框比一个独立的屏幕简单。在Android中弹出式对话框不同于表示一个屏幕的活动,它通常用于简单的功能处理。对话框可以设置标题、图标、最多三个按钮,其主要内容区域可以是提示信息、列表、单选按钮、复选框,甚至可以设置一个布局文件到其中。

在一个Activity中,实现方法是继承onCreateDialog()方法,返回一个Dialog类型:

        protected Dialog onCreateDialog(int id)

准备对话框的方法如下所示:

        protected void onPrepareDialog(int id, Dialog dialog)

对于一个id的对话框,onCreateDialog()会被调用一次,在每次对话框出现的时候,将调用onPrepareDialog()。

对话框的显示和取消如下所示:

        public final void showDialog (int id)        // 显示对话框
        public final void dismissDialog (int id)    // 取消对话框

当显示的时候需要调用showDialog(),让菜单消失使用dismissDialog()。以上的几个方法中,统一的内容是对话框的id。

android.app包中的Dialog实现了DialogInterface接口,其中几个方法如下所示:

        public void show()         // 显示对话框
        public void hide()         // 隐藏对话框
        public void dismiss()      // 消失对话框
        public void cancel()       // 取消对话框(比cancel()多调用一个注册的取消接口)

以下的几个接口用于处理对话框中的事件。

DialogInterface.OnCancelListener:取消对话框的事件;

DialogInterface.OnDismissListener:对话框消失的事件;

DialogInterface.OnClickListener:对话框的点击事件;

DialogInterface.OnKeyListener:对话框的按键事件

DialogInterface.OnMultiChoiceClickListener:对话框的多选项目。

几个接口中,较常使用的是DialogInterface.OnClickListener,它具有如下方法:

        public abstract void onClick (DialogInterface dialog, int which)

这里的onClick()的第一个参数为对话框的句柄,第二个参数表示对话框中的哪一个按钮发生了事件。

1.AlertDialog的基础

android.app包中的AlertDialog类是Dialog的主要继承者,可以用于建立一个提示对话框。AlertDialog.Builder类可以建立AlertDialog,在建立的过程中可以进行多项设置。

setIcon()和setTitle():用于设置图标和标题;

setMessage():用于设置提示信息;

setPositiveButton()、setNeutralButton()和setNegativeButton():用于设置左、中、右按钮的相关内容;

setSingleChoiceItems()和setMultiChoiceItems():用于设置单选项和复选项;

setView():用于设置一个View作为对话框的内容。

以上方法的返回类型均为android.app.AlertDialog.Builder,也就是这个类本身,因此可以使用如下的方式进行连续调用,来设置更多的内容。

AlertDialog.Builder中的create()和show()方法分别用于创建和显示对话框:

        public AlertDialog create ()        // 创建对话框
        public AlertDialog show ()          // 显示对话框

得到AlertDialog类之后,可以继续调用其中的方法进行设置工作。

参考示例程序:Dialog(ApiDemo=>App=>Dialog)

源代码:com/example/android/apis/app/AlertDialogSamples.java

Dialog程序中通过单击不同按钮将会启动不同的对话框,如图2-13所示。

图2-13 对话框程序

1. OK Cancel dialog with a message提示信息和两个按钮的对话框

2.OK Cancel dialog with a long message提示信息和三个按钮的对话框

3. List dialog列表项对话框

5. Single choice list单选项和按钮对话框

6. Repeat alarm复选项和按钮对话框

8. Text Entry dialog文本的按键对话框(使用布局文件)

2.提示信息和按钮

AlertDialog.Builder的基本功能是设置对话框标题和标识内容的信息,有以下几个方法:

        public AlertDialog.Builder  setTitle(CharSequence title)       //设置标题
        public AlertDialog.Builder setTitle(int titleId)               //设置标题
        public AlertDialog.Builder setIcon(int iconId)                 //设置图标
        public AlertDialog.Builder setMessage(CharSequence message)   //设置信息
        public AlertDialog.Builder setMessage(int messageId)          //设置信息

AlertDialog.Builder中的几个按钮的设置方法如下所示:

        public AlertDialog.Builder  setPositiveButton(int textId,
                                  DialogInterface.OnClickListener listener)
        public AlertDialog.Builder  setPositiveButton(CharSequence text,
                                  DialogInterface.OnClickListener listener)
        public AlertDialog.Builder  setNeutralButton(int textId,
                                  DialogInterface.OnClickListener listener)
        public AlertDialog.Builder  setNeutralButton(CharSequence text,
                                  DialogInterface.OnClickListener listener)
        public AlertDialog.Builder  setNegativeButton(int textId,
                                  DialogInterface.OnClickListener listener)
        public AlertDialog.Builder  setNegativeButton(CharSequence text,
                                  DialogInterface.OnClickListener listener)

其中PositiveButton表示左按钮;NeutralButton表示中按钮;NegativeButton表示右按钮,只有当以上的几个方法进行了设置之后,按钮才会出现。

在对话框程序中,第1个按钮(OK Cancel dialog with a message)启动一个提示信息和两个按钮的对话框,第2个按钮(OK Cancel dialog with a long message)启动一个提示信息和三个按钮的对话框。运行的效果如图2-14所示。

图2-14 提示信息和按钮运行效果(左:两个按钮的对话框;右:三个按钮和提示信息对话框)

以上的程序核心代码实现的片段如下所示:

        private static final int DIALOG_YES_NO_MESSAGE = 1;
        private static final int DIALOG_YES_NO_LONG_MESSAGE = 2;
        @Override
        protected Dialog onCreateDialog(int id) {
            switch (id) {
            case DIALOG_YES_NO_MESSAGE:
              return new AlertDialog.Builder(AlertDialogSamples.this)
                  .setIcon(R.drawable.alert_dialog_icon)               // 设置图标
                  .setTitle(R.string.alert_dialog_two_buttons_title)   // 设置标题
                  .setPositiveButton(R.string.alert_dialog_ok,
                                        new DialogInterface.OnClickListener() {
                      public void onClick(DialogInterface dialog, int whichButton) {
                          // 左键处理
                      }
                  })
                  // ......省略左按钮和右按钮的设置内容
                  .create();  // 得到AlertDialog
        // ......省略部分内容
            return null;
        }

一个AlertDialog对话框可以直接包含左、中、右三个按钮,这些按钮使用DialogInterface.OnClickListener作为接收事件的接口。在对应的onClick()方法中,传入的第1 个参数DialogInterface表示的是当前对话框的句柄。在第2 个对话框中,由于设置了setMessage(),因此将出现中间的长信息,作为对话框的主要内容。

3.列表项对话框

普通列表项使用AlertDialog.Builder的setItems()方法来完成,如下所示:

        AlertDialog.Builder  setItems(int itemsId,
                                        DialogInterface.OnClickListener listener)
        AlertDialog.Builder  setItems(CharSequence[] items,
                                        DialogInterface.OnClickListener listener)

setItems()方法的第1 个参数为字符串数组(可以使用资源文件表示),第2 个参数为DialogInterface.OnClickListener表示响应事件的方法。

对话框程序的第3个按钮(List dialog)启动一个列表项对话框,如图2-15所示。

图2-15 列表项对话框(左:列表项对话框;右:单击列表项后弹出的对话框)

程序将出现一个列表形式的对话框,当单击其中的一个项目的时候,将出现一个简单的新对话框。

代码实现的核心内容如下所示:

        case DIALOG_LIST:
        return new AlertDialog.Builder(AlertDialogSamples.this)
            .setTitle(R.string.select_dialog)
            .setItems(R.array.select_dialog_items,            // 设置对话框的列表项目
                      new DialogInterface.OnClickListener() { // 列表项的响应
              public void onClick(DialogInterface dialog, int which) {
                  String[] items =                            // 获得属性数组
                    getResources().getStringArray(R.array.select_dialog_items);
                    new AlertDialog.Builder(AlertDialogSamples.this)   // 建立对话框
                          .setMessage("You selected: " + which + " , " + items[which])
                          .show();                                       // 显示对话框

}

            })

这里使用了setItems()表示设置几个不同的项目,从res/values/array.xml文件中取得select_dialog_items的内容,表示一个数组,如下所示:

        <string-array name="select_dialog_items">
            <item>Command one</item>
            <item>Command two</item>
            <item>Command three</item>
            <item>Command four</item>
        </string-array>

由于DialogInterface.OnClickListener接口中的onClick()方法具有一个int型的which参数,根据这个参数可以得到是列表中的哪一个项目被单击。

这里对每一个列表项目也设置了单击方法,因此它们被单击后,也会弹出另一个新的对话框。这里首先使用AlertDialog.Builder建立对话框,然后调用show()方法直接显示对话框。这个新的对话框没有标题栏,只显示一段简单的文本消息。文本消息中显示出是哪一个列表项目被单击了。

4.单选项和复选项对话框

AlertDialog.Builder包含了直接生成单选项和复选框对话框的功能。使用它们建立的对话框的内容区域中,直接表示为单选项和复选框的形式。

单选项主要使用AlertDialog.Builder中的以下几个方法:

        AlertDialog.Builder  setSingleChoiceItems(CharSequence[] items,
            int checkedItem, DialogInterface.OnClickListener listener)
        AlertDialog.Builder  setSingleChoiceItems(int itemsId,
            int checkedItem, DialogInterface.OnClickListener listener)

复选项主要使用AlertDialog.Builder中的以下几个方法:

        AlertDialog.Builder  setMultiChoiceItems(CharSequence[] items,
            boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener)
        AlertDialog.Builder  setMultiChoiceItems(int itemsId,
            boolean[] checkedItems, DialogInterface.OnMultiChoiceClickListener listener)

单选项的事件直接使用DialogInterface.OnClickListener接口来进行接收。

多选项的事件使用DialogInterface.OnMultiChoiceClickListener接口用于接收,这个接口中的方法如下所示:

        public abstract void onClick (DialogInterface dialog, int which, boolean isChecked)

单选项需要有整型参数表示哪一个项目被选中,复选项有一个整型数组参数表示哪些项目被选中。因此,对于OnMultiChoiceClickListener的onClick()方法,每更改一个选项,它都会被调用一次,通知项目当前是否被选中(isChecked)。

对话框程序中,按钮(Single choice list)用于启动一个单选项和按钮对话框;按钮(Repeat alarm)用于启动一个复选项和按钮对话框,运行效果如图2-16所示。

图2-16 单选项和复选项对话框运行效果

单选项对话框的建立部分如下所示:

        case DIALOG_SINGLE_CHOICE:
            return new AlertDialog.Builder(AlertDialogSamples.this)
              .setIcon(R.drawable.alert_dialog_icon)
              .setTitle(R.string.alert_dialog_single_choice)
              .setSingleChoiceItems(R.array.select_dialog_items2,0, // 设置内容为单选
                  new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog, int whichButton) {
                          // ......处理单选项变化的内容
                  }
              })
              // ......省略左按钮和右按钮的设置内容
              .create();

单选项对话框建立的时候,使用setSingleChoiceItems()的第2个参数(boolean类型)表示初始化之后哪个元素目前被选中了。

复选项对话框的建立部分如下所示:

        case DIALOG_MULTIPLE_CHOICE:
            return new AlertDialog.Builder(AlertDialogSamples.this)
              .setIcon(R.drawable.ic_popup_reminder)
              .setTitle(R.string.alert_dialog_multi_choice)
              .setMultiChoiceItems(R.array.select_dialog_items3, // 设置内容为复选
                      new boolean[]{false, true, false, true, false, false, false},
                      new DialogInterface.OnMultiChoiceClickListener() {
                          public void onClick(DialogInterface dialog, int whicton,
                                  boolean isChecked) {
                          // ......处理复选项变化的内容
                          }
                      })
              // ......省略左按钮和右按钮的设置内容
              .create();

复选项对话框建立的时候,使用setMultiChoiceItems ()的第2个参数(boolean数组类型)表示每一个元素的初始化选择状态。

在本例中,使用资源文件res/values/array.xml,从中取得select_dialog_items2中的内容作为单选项的项目,从中取得select_dialog_items3中的内容作为复选项的项目。这种取出资源XML文件中的内容,相当于得到了一个CharSequence数组。

5.使用布局文件的对话框

在Android中使用对话框,可以在没有Activity的情况下建立一个比较简易的窗体,基本界面可以通过直接设置得到,通过AlertDialog.Builder的setView()可以获得任意内容的界面,如下所示:

        AlertDialog.Builder  setView(View view)

对话框示例程序的Text Entry dialog按钮将启动使用布局的对话框,效果如图2-17所示。

图2-17 使用布局文件对话框效果

使用布局文件的对话框的核心代码实现的片段如下所示:

        case DIALOG_TEXT_ENTRY:
            // This example shows how to add a custom layout to an AlertDialog
            LayoutInflater factory = LayoutInflater.from(this);
            final View textEntryView =   // 从布局文件中解析得到View
                      factory.inflate(R.layout.alert_dialog_text_entry, null);
            return new AlertDialog.Builder(AlertDialogSamples.this)
              .setIcon(R.drawable.alert_dialog_icon)
              .setTitle(R.string.alert_dialog_text_entry)
              .setView(textEntryView)  // 设置View为对话框的内容
          // ......省略左按钮和右按钮的设置内容
              })
              .create();

alert_dialog_text_entry.xml也是一个布局文件,其中包含了两个文本框和两个可编辑文本,这就是显示在屏幕上的内容,根据这种模式,也可以在弹出的对话框中使用布局文件。由此,在这个对话框中,包含了这些相应的控件。

2.5.3 标题栏的使用

标题栏通常出现在一个Activity的最上部,标题栏本身也属于Activity的一部分。可以通过代码定制标题栏的内容,甚至将标题栏设置成一个布局文件。

标题栏的基本设置可以通过Activity中的以下几个方法来实现:

        public void setTitle(int titleId)            // 设置标题栏文字
        public void setTitle(CharSequence title)    // 设置标题栏文字
        public void setTitleColor(int textColor)    // 设置标题栏文字颜色

标题栏还可以进行进一步的设置。进一步的设置需要使用android.view包中的Window抽象类。在Activity中使用getWindow()方法获得其中Window的句柄。

Window中的两个方法和标题栏的设置相关,如下所示:

        public boolean requestFeature (int featureId)                  // 申请特性
        public abstract void setFeatureInt(int featureId, int value)  // 设置特性

featureId为一个整数,可以使用以下几个数值和标题栏的设置相关。

FEATURE_NO_TITLE:无标题栏;

FEATURE_PROGRESS和FEATURE_INDETERMINATE_PROGRESS:使用进度条,前者为水平进度条,后者为圆形标志;

FEATURE_LEFT_ICON和FEATURE_RIGHT_ICON:使用图标;

FEATURE_CUSTOM_TITLE:通过布局文件,自定义标题栏。

自定义标题栏示例程序:(ApiDemo=>App=>CustomTitle)

源文件:com/example/android/apis/app/CustomTitle.java

布局资源文件:custom_title.xml(内容布局)和custom_title_1.xml(标题栏布局)

自定义标题栏程序运行结果如图2-18所示。

图2-18 自定义标题栏程序运行结果(左:初始化界面;右:设置后界面)

自定义标题栏程序的核心部分如下所示:

            @Override
            protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);      // 申请特性
              setContentView(R.layout.custom_title);
              getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, // 自定义标题栏特性
                                          R.layout.custom_title_1);
        // 查找布局文件View
              final TextView leftText = (TextView) findViewById(R.id.left_text);
              final TextView rightText = (TextView) findViewById(R.id.right_text);
        // ...... 省略其他的内容
        }

调用requestWindowFeature()和setFeatureInt()设置自定义标题栏,其中setFeatureInt()的第2个参数为布局文件的整型id。

custom_title_1.xml是标题栏使用的布局文件,其内容如下所示:

        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/screen"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView android:id="@+id/left_text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentLeft="true"
              android:text="@string/custom_title_left" />
            <TextView android:id="@+id/right_text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentRight="true"
              android:text="@string/custom_title_right" />
        </RelativeLayout>

在标题栏程序中具有两个文本,一个靠左,一个靠右,这些就是由custom_title_1文件定义的。使用自定义标题栏的方法,可以将标题栏设置为一个布局文件。当设置完成后,使用Activity的findViewById()方法可以找到标题栏布局文件中的控件。

提示:通常不需要自定义过于复杂的标题栏,当需要复杂的标题区域的时候可以设置为没有标题栏,所有需要在界面上显示的内容在布局文件中定义。