2013-10-28

【Android】啟用 Support Library 的 ActionBar

資料來源 ----
https://developer.android.com/design/patterns/actionbar.html
http://developer.android.com/training/basics/actionbar/index.html
http://developer.android.com/guide/topics/ui/actionbar.html

Material Icons

 

ActionBar 是自 Andoird 3.0(API level 11) 加入的新功能,目的在增進使用者操作介面更豐富並統一介面外觀;為了讓舊版本的 Android 也能有 ActionBar,又推出 appcompat v7 提供舊 Android 版本的 API,可往前支援到 Android 2.1(Éclair, API level 7)


如果您希望您的 app 要安裝在 Android 2.1~2.3.3 的裝置(也就是 7<= minSdkVersion <=10),且 Activity 想要有具 ActionBar 的外觀,則您需要先 設定 Support Library

本篇筆記的重點在使用 Support Library 的 ActionBar。

設定好 Support Library 後,建立一個新的 Android 專案,專案命名為 V7,刻意將 Minimum Required SDK 定在 API 8


在專案點滑鼠右鍵
→  Properties
→  出現 Properties for V7 視窗
→  點選左方的 Android
→  捲動右方的捲軸到最下方
→  按 Add
→  選取 android-support-v7-appcompat



修改 MainActivity 繼承自 ActionBarActivity,並修改 onCreateOptionsMenu()

package com.example.v7;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;

...
...

public class MainActivity extends ActionBarActivity 
{

    ...
    ...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }
    
    ...
    ...

修改 AndroidManifest.xml加入 android:theme="@style/Theme.AppCompat.Light"
...
...

<activity
    android:name="com.example.v7.MainActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.AppCompat.Light" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

...
...




除了 Theme.AppCompat.LightSupport Library 還提供了
Theme.AppCompat 
Theme.AppCompat.Light.DarkActionBar
一共 3 種預設的主題樣式。

Google 提供了一整套的 ActionBar 圖示讓開發人員下載使用,Material Icons,解壓後,在 /Action_Bar_Icons/holo_dark//Action_Bar_Icons/holo_light/ 找到您要的圖示複製到專案下對應位置,在本例,複製了 neweditdiscardsearch 等圖示。
 建立 ActionBar 的功能表 -- 修改預設的 /menu/main.xml
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:v7="http://schemas.android.com/apk/res-auto" >
    <!-- 注意這裡 --> 

    <!-- 新增, 要顯示 -->
    <item android:id="@+id/action_new"
          android:icon="@drawable/ic_action_new"
          android:title="@string/action_new"
          v7:showAsAction="ifRoom" />
    <!-- 注意這裡 -->

    <!-- 修改, 要顯示 -->
    <item android:id="@+id/action_edit"
          android:icon="@drawable/ic_action_edit"
          android:title="@string/action_edit"
          v7:showAsAction="ifRoom" />
    <!-- 注意這裡 -->

    <!-- 丟棄, 要顯示 -->
    <item android:id="@+id/action_discard"
          android:icon="@drawable/ic_action_discard"
          android:title="@string/action_discard"
          v7:showAsAction="ifRoom" />
    <!-- 注意這裡 -->

    <!-- 尋找, 要顯示 -->
    <item android:id="@+id/action_search"
          android:icon="@drawable/ic_action_search"
          android:title="@string/action_search"
          v7:showAsAction="ifRoom" />
    <!-- 注意這裡 -->

    <!-- Settings, 不顯示, 按 "MENU" 鈕才會看到 -->
    <item android:id="@+id/action_settings"
          android:title="@string/action_settings"
          android:showAsAction="never" />
</menu>

注意第 3 列

xmlns:識別字="http://schemas.android.com/apk/res-auto"

一定要加上這段文字,才能讓舊版本的 Android 在 ActionBar 顯現圖示;其中 "識別字" 您可任意命名,習慣上就是直接採用您 app 專案名,像本例專案名為 v7


而每個 item 的最後一列

識別字:showAsAction="ifRoom"

ifRoom 表示若 ActionBar 有足夠的空間則顯現本圖示,若空間不夠,則其餘未顯現的圖示會出現在 MENU 功能表中。


上圖在 ActionBar 只出現 2 個圖示 -- 新增 & 修改,其餘列在功能表中。

如果硬要這個 item 的圖示出現在 ActionBar,則為

識別字:showAsAction="always"



不過 Android 開發團隊並不鼓勵,因為各種尺寸、解析度的 Android 裝置太多,這個設定值可能導致 Activity 顯示時發生無法預知的後果...

當您長按 ActionBar 的圖示時,螢幕會出現該圖示的說明文字
 
如果希望強制出現文字,則要再加上 withText

識別字:showAsAction="ifRoom|withText"

gingerbread(android 2.3.3, API level 10), 3.7吋 hdpi 橫向畫面
仍然只出現 2 個圖示(showAsAction="ifRoom"),猜想應該是 ActionBar 在 舊版本的 Android 裝置只能顯現 2 個圖示吧...


ICS(android 4.0.3, API level 15), 3.7吋 hdpi 橫向畫面


當按鈕很多而 ActionBar 無法全部顯示時,

meta-data android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow"

會將 ActionBar 分割為上、下 2 部份,並在下部的 ActionBar 顯示更多的按鈕,不過,實驗後,下部好像也只能顯示 3 個按鈕而已...

<activity
    android:name="com.example.v7.MainActivity"
    android:label="@string/app_name"
    android:theme="@style/Theme.AppCompat.Light" >
            
    <meta-data android:name="android.support.UI_OPTIONS"
           android:value="splitActionBarWhenNarrow" />
            
    ...
    ...


</activity>





最後就是 ActionBar 各圖示的 click 事件處理,其實就是功能表的 click 事件處理

...
...

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
    // Handle presses on the action bar items
    switch (item.getItemId()) 
    {
        case R.id.action_search:
            openSearch();
            return true;
        case R.id.action_edit:
            openEdit();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
 
public void openSearch()
{
    Toast.makeText(this, "按了 尋找 鈕", Toast.LENGTH_LONG).show();
}
 
public void openEdit()
{
    Toast.makeText(this, "按了 Edit 鈕", Toast.LENGTH_LONG).show();
}

...
...


相關筆記 ----
設定 Support Library
ActionBar 加入返回鍵
【Android Studio】回傳資料給 Parent Activity

11 則留言:

  1. 不好意思,請問一下
    為什麼現在開新專案時
    在最後確認名稱那裏會出現fragment layout?
    我已經沒有載入supprot library
    跟之前的不太一樣
    要怎樣才能把fragment layout用掉呢?

    回覆刪除
  2. 拍謝, 我也還在學習中...

    回覆刪除
  3. 請問
    我在開新專案後,
    底下出現Warnings
    "The import android.support.v7.app.ActionBar is never used MainActivity.java "
    是不是跟設定 Support Library有關??

    回覆刪除
  4. 如果我沒誤解,這應該只是個警告,提示您雖然引用了 ActionBar,但您的 MainActivity 卻未使用 ActionBar 的功能。
    不影響 app 的執行。

    回覆刪除
  5. 請問一下
    可不可以不要讓它出現 setting 的圖示 試過把整個item的程式碼給刪掉 還試了never 似乎都沒辦法成功

    回覆刪除
  6. 不懂...筆記裡, settings 沒圖示啊...
    如果您是指 功能表中 settings 選項不要顯示, 那就刪除 /menu/main.xml 最後一項

    回覆刪除
  7. 你是說這個嗎

    可是我刪了之後好像就會出錯

    回覆刪除
  8. 不好意思我想請問


    public boolean onCreateOptionMenu(Menu menu){
    //Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main,menu);
    ↑↑↑↑↑↑↑↑這裡 menu_ main 會顯示錯誤 要如何修正
    return true;

    回覆刪除
  9. 這是舊筆記了,請改用 Android Studio。

    回覆刪除