1. 程式人生 > >Android UI開發之Action Bar

Android UI開發之Action Bar

什麼是Action Bar呢

   ActionBarAndroid 3.0(API level 11)引入的一個新控制元件,它代表了應用程式標題欄,如果要開發相容的程式,可以使用v7包下的ActionBarAction Bar取代了傳統的tittle bar和menu,在程式執行中一直置於頂部,對於Android平板裝置來說螢幕更大它的標題使用Action Bar來設計可以展示更多豐富的內容,方便操控。

  通過官方API可以看到:

  The action bar is a window feature that identifies the user location, and provides user actions and navigation modes. Using the action bar offers your users a familiar interface across applications that the system gracefully adapts for different screen configurations.


         

 An action bar that includes the [1] app icon, [2] two action items, and [3] action overflow.

General Organization

The action bar is split into four different functional areas that apply to most apps.


1.App icon: 應用的圖示,左側圖示說明可以觸控返回,相當於觸控 back 返回鍵

2.ViewControl: 下拉列表導航

3.Action button:

 相當於普通的 Button 可以監聽點選事件

4.Action overflow: 三個點,相當於手機上的 menu 鍵,可以顯示隱藏的 action button

在使用Action Bar之前,要注意:

如果API低於11,要匯入android.support.v7.app.ActionBar

如果API高於11,要匯入 android.app.ActionBar

如何使用ActionBar呢

(1)匯入android-support-v7庫,這個庫其實在你的sdk裡面就有(前提是你已經下載下來了),如我的路徑:D:\android-sdk-windows\extras\android\support\v7\appcompat


  

(2)Activity要繼承自ActionBarActivity,在Manifest檔案中為Application或者Activity設定主題為Theme.AppCompat或其子主題,例如:
<activity android:theme:"@style/Theme.AppCompat.Light" ...>

   

    

    

效果圖如下:

  

一般情況下,ActionBar的app Icon使用你在Manifest檔案中為<application>或<activity>元素指定的icon屬性的圖片,在這裡不知道為什麼沒有顯示,下面通過新增程式碼的方法將icon調出。

通過在MainActivity下新增以下程式碼,可以設定自己喜歡的icon。

        ActionBar actionBar = getSupportActionBar();
        actionBar.setLogo(R.mipmap.ic_launcher);
        actionBar.setDisplayUseLogoEnabled(true);
        actionBar.setDisplayShowHomeEnabled(true);
可以看到,logo已經出來。logo的修改也是通過上述方法實現的。

      

隱藏ActionBar

如果想要隱藏ActionBar,有以下兩個方法可以隱藏。

(1)修改Activity的主題。

style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"
(2)通過程式碼實現
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();
   這裡要提醒一下:由於ActionBar在隱藏的時候會重現繪製Activity的介面,從而填充ActionBar的空白,所以當你頻繁的隱藏和顯示ActionBar時,會導致Activity的介面頻繁重繪,為了避免這種情況發生,你可以再actionBarStyle中將 windowActionBarOverlay這個屬性設定為true,也就是說ActionBar會在Activity的上面,隱藏和顯示不會影響Activity。

在應用中新增ActionBar

1.res/menu/目錄中修改menu_main.xml,程式碼如下:

<pre name="code" class="java"><menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.ahuang.actionbar.MainActivity">
   <item
       android:id="@+id/icon_save"
       android:orderInCategory="100"
       android:icon="@drawable/ic_action_save"
       android:title="@string/save"
       app:showAsAction="ifRoom|withText"></item>
    <item
        android:id="@+id/icon_delete"
        android:orderInCategory="100"
        android:icon="@drawable/ic_action_discard"
        android:title="@string/delete"
        app:showAsAction="ifRoom|withText"></item>
    <item
        android:id="@+id/icon_email"
        android:orderInCategory="100"
        android:icon="@drawable/ic_action_email"
        android:title="@string/email"
        app:showAsAction="ifRoom"></item>
    <item
        android:id="@+id/icon_import"
        android:orderInCategory="100"
        android:icon="@drawable/ic_action_important"
        android:title="@string/inport"
        app:showAsAction="ifRoom"></item>
    <item
        android:id="@+id/icon_setting"
        android:orderInCategory="100"
        android:icon="@drawable/ic_action_settings"
        android:title="@string/setting"
        app:showAsAction="ifRoom"></item>
</menu>

說明一下幾個屬性的意思。

屬性名

解釋

android:orderInCategory

表示每個 item 的優先順序,值越大優先順序越低,actionbar 地方不夠就會放到 overflow 中。

android:title

item 的標題。

android:icon

item 顯示的圖示。

app:showAsAction

item 顯示的方式。

showAsAction屬性接受如下一些值:

ifRoom

會顯示在 Item 中,但是如果已經有 4 個或者 4 個以上的Item 時會隱藏在溢位列表中。當然個數並不僅僅侷限於 4個,依據螢幕的寬窄而定

never

永遠不會顯示。只會在溢位列表中顯示,而且只顯示標題,所以在定義 item 的時候,最好把標題都帶上。

always

無論是否溢位,總會顯示。

  withText

withText 值示意 Action bar 要顯示文字標題。 Action bar會盡可能的顯示這個標題,但是,如果圖示有效並且受到Action bar 空間的限制,文字標題有可能顯示不全。

collapseActionView

聲明瞭這個操作視窗應該被摺疊到一個按鈕中,當用戶選擇這個按鈕時,這個操作視窗展開。否則,這個操作視窗在預設的情況下是不可見的。一般要配合 ifRoom 一起使用才會有效果。

2.重寫ActionBarActivity中的onCreateOptionsMenu()方法。
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
3.重寫onOptionsItemSelected()監聽事件;
<pre name="code" class="java">@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        switch (id){
            case R.id.icon_save:
                return true;
            case R.id.icon_delete:
                return true;
            case R.id.icon_setting:
                return true;
            case R.id.icon_email:
                return true;
            case R.id.icon_import:
                return true;
        }

        return super.onOptionsItemSelected(item);
    }


執行效果如圖所示:        顯示OverflowMenu的Icon

在Activity下新增以下兩個方法

@Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        setOverflowIconVisible(featureId, menu);
        return super.onMenuOpened(featureId, menu);
    }

    /**
     * 利用反射讓隱藏在Overflow中的MenuItem顯示Icon圖示
     * @param featureId
     * @param menu
     * onMenuOpened方法中呼叫
     */
    public static void setOverflowIconVisible(int featureId, Menu menu) {
        if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
            if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
                try {
                    Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                } catch (Exception e) {
                }
            }
        }
    }
          

ActionBar的導航功能

ActionBar最重要的功能就是其導航功能,使用其導航功能時,需要進行如下配置

1、顯示導航按鈕

ActionBar actionBar = getSupportActionBar();

actionBar.setDisplayHomeAsUpEnabled(true);

配置完了後,執行如下圖,你會發現Actionbar多了一個類似返回的icon

       

然後為導航新增事件
actionBar.setDisplayHomeAsUpEnabled(true); //<span style="color: rgb(0, 130, 0); font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 14px; line-height: 15.4px; white-space: pre;">這句就可以讓actionBar的圖示可以響應點選事件</span>

然後在onOptionsItemSelected()方法裡新增如下分支:
case android.R.id.home:
                Intent intent=new Intent(this,MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                finish();
                return true;
這樣點選ActionBar會跳到主Activity。

ActionBar實現搜尋檢視

1.新增搜尋Item

<item
        android:id="@+id/icon_serch"
        android:orderInCategory="100"
        android:icon="@drawable/ic_action_search"
        android:title="搜尋"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="collapseActionView|ifRoom"></item>
2.在Activity裡寫一個方法實現ActionBar的搜尋功能。並在onCreateOptionsMenu()方法裡呼叫。
/**
     * 為ActionBar實現查詢功能
     * @param menu
     */

    private void setSearch(Menu menu){
        final MenuItem item=menu.findItem(R.id.icon_serch);
        SearchView sv=(SearchView) MenuItemCompat.getActionView(item);
        if(sv!=null){
            sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String s) {
                    MenuItemCompat.collapseActionView(item);
                    return true;
                }

                @Override
                public boolean onQueryTextChange(String s) {
                    return false;
                }
            });
        }


    }
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        setSearch(menu);
        return true;
    }
3.在onOptionsItemSelected()方法裡新增響應事件。
case R.id.icon_serch:
                return true;