1. 程式人生 > >Android 頂部標題欄ActionBar詳解

Android 頂部標題欄ActionBar詳解

轉載自http://www.cnblogs.com/yc-755909659/p/4290784.html

一、ActionBar介紹

  在Android 3.0中除了我們重點講解的Fragment外,Action Bar也是一個非常重要的互動元素,Action Bar取代了傳統的tittle bar和menu,在程式執行中一直置於頂部,對於Android平板裝置來說螢幕更大它的標題使用Action Bar來設計可以展示更多豐富的內容,方便操控。

二、ActionBar的功能

  用圖的方式來講解它的功能

  

  <1> ActionBar的圖示,可顯示軟體圖示,也可用其他圖示代替。當軟體不在最高階頁面時,圖示左側會顯示一個左箭頭,使用者可以通過這個箭頭向上導航;

  <2> 如果你的應用要在不同的View中顯示資料,這部分允許使用者來切換檢視。一般的作法是用一個下拉選單或者是Tab選項卡。如果只有一個介面,那這裡可以顯示應用程式的標題或者是更長一點的商標資訊;

  <3> 兩個action按鈕,這裡放重要的按鈕功能,為使用者進行某項操作提供直接的訪問;

  <4> overflow按鈕,放不下的按鈕會被置於“更多...”選單項中,“更多...”選單項是以下拉形式實現的。

三、ActionBar 奧義·詳解

1、新增ActionBar

    ActionBar的新增非常簡單,只需要在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子類就可以了,在Android 3.0及更高的版本中,Activity中都預設包含有ActionBar元件。

2、取消ActionBar

如果需要隱藏Action Bar可以在你的Activity的屬性中設定主題風格為NoTitleBar在你的manifest檔案中

<activity android:theme="@android:style/Theme.NoTitleBar">

  還有一種做法,在執行時呼叫hide()方法也可以隱藏ActionBar,呼叫show()方法來顯示ActionBar()。

ActionBar actionBar = getActionBar();  
actionBar.hide();  

  當你隱藏ActionBar時,系統會將Activity的整個內容充滿整個空間。

  注意:如果使用一個主題(theme)來移除Activity上得ActionBar,那麼視窗將不再會有ActionBar,因此在執行時也就沒有辦法來新增ActionBar——呼叫getActionBar()方法會返回null值。

3.修改Action Bar的圖示和標題

預設情況下,系統會使用<application>或者<activity>中icon屬性指定的圖片來作為ActionBar的圖示,但是我們也可以改變這一預設行為。如果我們想要使用另外一張圖片來作為ActionBar的圖示,可以在<application>或者<activity>中通過logo屬性來進行指定,而標題中的內容使用label屬性來指定。比如專案的res/drawable目錄下有一張cnblog_icon.png圖片,就可以在AndroidManifest.xml中這樣指定:

 <activity
            android:name=".MainActivity"
            android:label="召喚ActionBar吧"
            android:logo="@drawable/cnblog_icon" >

效果圖如下:

4.新增Action按鈕

ActionBar還可以根據應用程式當前的功能來提供與其相關的Action按鈕,這些按鈕都會以圖示或文字的形式直接顯示在ActionBar上。當然,如果按鈕過多,ActionBar上顯示不完,多出的一些按鈕可以隱藏在overflow裡面(最右邊的三個點就是overflow按鈕),點選一下overflow按鈕就可以看到全部的Action按鈕了。

當Activity啟動的時候,系統會呼叫Activity的onCreateOptionsMenu()方法來取出所有的Action按鈕,我們只需要在這個方法中去載入一個menu資源,並把所有的Action按鈕都定義在資原始檔裡面就可以了。 那麼我們先來看下menu資原始檔該如何定義,程式碼如下所示: 複製程式碼
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/user_p"
        android:icon="@drawable/icon_user_p"
        android:showAsAction="always"
        android:title="使用者"/>
    <item
        android:id="@+id/write_p"
        android:icon="@drawable/icon_write_p"
        android:showAsAction="always"
        android:title="釋出"/>
    <item
        android:id="@+id/favo_p"
        android:icon="@drawable/icon_favo_p"
        android:showAsAction="never"
        android:title="收藏"/>

</menu>
複製程式碼

可以看到,這裡我們通過兩個<item>標籤定義了三個Action按鈕。<item>標籤中又有一些屬性,其中id是該Action按鈕的唯一識別符號,icon用於指定該按鈕的圖示,title用於指定該按鈕可能顯示的文字(在圖示能顯示的情況下,通常不會顯示文字),actionViewClass用來指定一個構建視窗所使用的佈局資源,showAsAction則指定了該按鈕顯示的位置,主要有以下幾種值可選:

fRoom 會顯示在Item中,但是如果已經有4個或者4個以上的Item時會隱藏在溢位列表中。當然個
數並不僅僅侷限於4個,依據螢幕的寬窄而定
never 永遠不會顯示。只會在溢位列表中顯示,而且只顯示標題,所以在定義item的時候,最好
把標題都帶上。
always 無論是否溢位,總會顯示。
withText withText值示意Action bar要顯示文字標題。Action bar會盡可能的顯示這個
標題,但是,如果圖示有效並且受到Action bar空間的限制,文字標題有可
能顯示不全。
   collapseActionView   聲明瞭這個操作視窗應該被摺疊到一個按鈕中,當用戶選擇這個按鈕時,這個操作視窗展開。否則,
這個操作視窗在預設的情況下是可見的,並且即便在用於不適用的時候,也要佔據操作欄的有效空間。
一般要配合ifRoom一起使用才會有效果。

接著,重寫Activity的onCreateOptionsMenu()方法,程式碼如下所示:

複製程式碼
@Override 
public boolean onCreateOptionsMenu(Menu menu) {  
    MenuInflater inflater = getMenuInflater();  
    inflater.inflate(R.menu.menu_main, menu);  
return super.onCreateOptionsMenu(menu);  
}  
複製程式碼

這部分程式碼很簡單,僅僅是呼叫了MenuInflater的inflate()方法來載入menu資源就可以了。現在重新執行一下程式,結果如下圖所示:

可以看到,menu_search和menu_setting這兩個按鈕已經在ActionBar中顯示出來了,而menu_delete這個按鈕由於showAsAction屬性設定成了never,所以被隱藏到了overflow當中,只要點選一下overflow按鈕就可以看到它了。

這裡我們注意到,顯示在ActionBar上的按鈕都只有一個圖示而已,我們在title中指定的文字並沒有顯示出來。沒錯,title中的內容通常情況下只會在overflow中顯示出來,ActionBar中由於螢幕空間有限,預設是不會顯示title內容的。但是出於以下幾種因素考慮,即使title中的內容無法顯示出來,我們也應該給每個item中都指定一個title屬性:
  • 當ActionBar中的剩餘空間不足的時候,如果Action按鈕指定的showAsAction屬性是ifRoom的話,該Action按鈕就會出現在overflow當中,此時就只有title能夠顯示了。
  • 如果Action按鈕在ActionBar中顯示,使用者可能通過長按該Action按鈕的方式來檢視到title的內容。

5.響應Action按鈕的點選事件

當用戶點選Action按鈕的時候,系統會呼叫Activity的onOptionsItemSelected()方法,通過方法傳入的MenuItem引數,我們可以呼叫它的getItemId()方法和menu資源中的id進行比較,從而辨別出使用者點選的是哪一個Action按鈕,比如:

複製程式碼
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {  
         case R.id.user_p:  
                Toast.makeText(this, "你點選了“使用者”按鍵!", Toast.LENGTH_SHORT).show();  
                return true;  
            case R.id.write_p:  
                Toast.makeText(this, "你點選了“釋出”按鍵!", Toast.LENGTH_SHORT).show();  
                return true;  
            case R.id.favo_p:  
                Toast.makeText(this, "你點選了“收藏”按鍵!", Toast.LENGTH_SHORT).show();  
                return true;  
            default:  
                return super.onOptionsItemSelected(item);  
            }  
    }
複製程式碼

可以看到,我們讓每個Action按鈕被點選的時候都彈出一個Toast,現在重新執行一下程式碼,結果如下圖所示:

5.通過Action Bar圖示進行導航

啟用ActionBar圖示導航的功能,可以允許使用者根據當前應用的位置來在不同介面之間切換。比如,A介面展示了一個列表,點選某一項之後進入了B介面,這時B介面就應該啟用ActionBar圖示導航功能,這樣就可以回到A介面。

我們可以通過呼叫setDisplayHomeAsUpEnabled()方法來啟用ActionBar圖示導航功能,比如:
setTitle("Yanis");  
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();  
actionBar.setDisplayHomeAsUpEnabled(true); 

現在重新執行一下程式,結果如下圖所示:

可以看到,在ActionBar圖示的左側出現了一個向左的箭頭,通常情況下這都表示返回的意思,因此最簡單的實現就是在它的點選事件裡面加入finish()方法就可以了,如下所示:

複製程式碼
switch (item.getItemId()) {  
        case android.R.id.home:  
            finish();
            return true; 
        ...
        }  
複製程式碼 當點選ActionBar圖示的時候,系統同樣會呼叫onOptionsItemSelected()方法,並且此時的itemId是android.R.id.home,所以finish()方法也就是加在這裡的了。 現在看上去,ActionBar導航和Back鍵的功能貌似是一樣的。沒錯,如果我們只是簡單地finish了一下,ActionBar導航和Back鍵的功能是完全一樣的,但ActionBar導航的設計初衷並不是這樣的,它和Back鍵的功能還是有一些區別的,舉個例子吧。 上圖中的Conversation List是收件箱的主介面,現在我們點選第一封郵件會進入到Conversation1 details介面,然後點選下一封郵件會進入到Conversation 2 details介面,再點選下一封郵箱會進入到Conversation3 details介面。好的,這個時候如果我們按下Back鍵,應該會回到Conversation 2 details介面,再按一次Back鍵應該回到Conversation1 details介面,再按一次Back鍵才會回到Conversation List。而ActionBar導航則不應該表現出這種行為,無論我們當前在哪一個Conversation details介面,點選一下導航按鈕都應該回到Conversation List介面才對。 這就是ActionBar導航和Back鍵在設計上的區別,那麼該怎樣才能實現這樣的功能呢?其實並不複雜,實現標準的ActionBar導航功能只需三步走。 第一步我們已經實現了,就是呼叫setDisplayHomeAsUpEnabled()方法,並傳入true。

第二步需要在AndroidManifest.xml中配置父Activity,如下所示:

 <activity android:name="com.yanis.actionbar.TabActivity">
             <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.yanis.actionbar.MainActivity" />
        </activity>

可以看到,這裡通過meta-data標籤指定了MainActivity的父Activity是LaunchActivity,在Android 4.1版本之後,也可以直接使用android:parentActivityName這個屬性來進行指定,如下所示:

<activity 
    android:name="com.yanis.actionbar.TabActivity"
    android:parentActivityName="com.yanis.actionbar.MainActivity" > 
</activity> 

第三步則需要對android.R.id.home這個事件進行一些特殊處理,如下所示:

複製程式碼
@Override 
public boolean onOptionsItemSelected(MenuItem item) {  
    switch (item.getItemId()) {  
    case android.R.id.home:  
        Intent upIntent = NavUtils.getParentActivityIntent(this);  
        if (NavUtils.shouldUpRecreateTask(this, upIntent)) {  
            TaskStackBuilder.create(this)  
                    .addNextIntentWithParentStack(upIntent)  
                    .startActivities();  
        } else {  
            upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
            NavUtils.navigateUpTo(this, upIntent);  
        }  
        return true;  
        ......  
    }  
}  
複製程式碼

其中,呼叫NavUtils.getParentActivityIntent()方法可以獲取到跳轉至父Activity的Intent,然後如果父Activity和當前Activity是在同一個Task中的,則直接呼叫navigateUpTo()方法進行跳轉,如果不是在同一個Task中的,則需要藉助TaskStackBuilder來建立一個新的Task。

這樣,就按照標準的規範成功實現ActionBar導航的功能了。 效果圖如下:

6.新增Action View

ActionView是一種可以在ActionBar中替換Action按鈕的控制元件,它可以允許使用者在不切換介面的情況下通過ActionBar完成一些較為豐富的操作。比如說,你需要完成一個搜尋功能,就可以將SeachView這個控制元件新增到ActionBar中。

為了宣告一個ActionView,我們可以在menu資源中通過actionViewClass屬性來指定一個控制元件,還記得前面寫過的嗎:
<item
        android:id="@+id/action_search"
        android:actionViewClass="android.widget.SearchView"
        android:showAsAction="always"
        android:title="搜尋"/>

如果你還希望在程式碼中對SearchView的屬性進行配置(比如新增監聽事件等),完全沒有問題,只需要在onCreateOptionsMenu()方法中獲取該ActionView的例項就可以了,程式碼如下所示:

複製程式碼
@Override 
public boolean onCreateOptionsMenu(Menu menu) {  
    MenuInflater inflater = getMenuInflater();  
    inflater.inflate(R.menu.main, menu);  
    MenuItem searchItem = menu.findItem(R.id.action_search);  
    SearchView searchView = (SearchView) searchItem.getActionView();  
    // 配置SearchView的屬性  
    ......  
    return super.onCreateOptionsMenu(menu);  
}  
複製程式碼

除此之外,有些程式可能還希望在ActionView展開和合並的時候顯示不同的介面,其實我們只需要去註冊一個ActionView的監聽器就能實現這樣的功能了,程式碼如下所示:

複製程式碼
@Override 
public boolean onCreateOptionsMenu(Menu menu) {  
    MenuInflater inflater = getMenuInflater();  
    inflater.inflate(R.menu.main, menu);  
    MenuItem searchItem = menu.findItem(R.id.action_search);  
    searchItem.setOnActionExpandListener(new OnActionExpandListener() {  
        @Override 
        public boolean onMenuItemActionExpand(MenuItem item) {  
            Log.d("TAG", "on expand");  
            return true;  
        }  
          
        @Override 
        public boolean onMenuItemActionCollapse(MenuItem item) {  
            Log.d("TAG", "on collapse");  
            return true;  
        }  
    });  
    return super.onCreateOptionsMenu(menu);  
}  
複製程式碼

可以看到,呼叫MenuItem的setOnActionExpandListener()方法就可以註冊一個監聽器了,當SearchView展開的時候就會回撥onMenuItemActionExpand()方法,當SearchView合併的時候就會呼叫onMenuItemActionCollapse()方法,我們在這兩個方法中進行相應的UI操作就可以了。

7.Overflow按鈕不顯示的情況

雖然現在我們已經掌握了不少ActionBar的用法,但是當你真正去使用它的時候還是可能會遇到各種各樣的問題,比如很多人都會碰到overflow按鈕不顯示的情況。明明是同樣的一份程式碼,overflow按鈕在有些手機上會顯示,而在有些手機上偏偏就不顯示,如下圖:

可以看到,ActionBar最右邊的overflow按鈕不見,按一下Menu鍵,隱藏在overflow中的Action按鈕就會從底部出來。

有人總結了一下,overflow按鈕的顯示情況和手機的硬體情況是有關係的,如果手機沒有物理Menu鍵的話,overflow按鈕就可以顯示,如果有物理Menu鍵的話,overflow按鈕就不會顯示出來。比如我們啟動一個有Menu鍵的模擬器,然後將程式碼執行到該模擬器上

實際上,在ViewConfiguration這個類中有一個叫做sHasPermanentMenuKey的靜態變數,系統就是根據這個變數的值來判斷手機有沒有物理Menu鍵的。當然這是一個內部變數,我們無法直接訪問它,但是可以通過反射的方式修改它的值,讓它永遠為false就可以了,程式碼如下所示:

複製程式碼
@Override 
protected void
            
           

相關推薦

Android 頂部標題ActionBar

轉載自http://www.cnblogs.com/yc-755909659/p/4290784.html 一、ActionBar介紹   在Android 3.0中除了我們重點講解的Fragment外,Action Bar也是一個非常重要的互動元素,Ac

android簡訊資料庫

資料庫中sms相關的欄位如下:      _id                      primary key     integer                  與words表內的source_id關聯 thread_id              會話id,一

Android原生控制元件---ActionBar

昨天去面試了,第一次出去面試,被問到好幾個我不好回答上來的題,例如OOM的處理啊,AndroidStudio的gradle配置,actionBar的使用,ViewPager 巢狀ViewPager等等

android去掉對話方塊Dialog頂部標題

//對話方塊 CloseAppDialog dialog = new CloseAppDialog(context);

[Android] 自定義頂部標題

思路及實現步驟 1.定義標題欄佈局 2.自定義TitleActivity控制標題欄按鈕監聽 3.在TitleActivity中實現標題欄以下內容切換 效果如下: 首先定義標題欄 layout_title.xml <?xml v

Android自定義主題樣式(結合自定義title講解)

此篇部落格將總結主題樣式的自定義並且結合例項自定義title欄進行講解。為了方便閱讀,在此先寫明文章結構: 1.對android主題樣式的理解 (簡略結合系統自帶樣式的講解) 2.如何自定義主題樣式 (主要,有例子) 3.如何自定義titl

Android Studio如何去除頂部標題

1、開啟 res -> values -> styles ;2.修改 DarkActionBar 為 NoActionBar。預設AppTheme:<style name="AppTheme" parent="Theme.AppCompat.Light.Da

Android學習筆記》Android Studio如何去除頂部標題教程

【更新時間】 2017/4/5 【序】 在初步開發Android應用中,我們會遇到一個問題,頂部標題欄的名字是專案名字(app名字)並且不可編輯。非常的不方便,那麼我們有什麼辦法把他去掉呢? 【相關文章】 【開發工具】 Android

Android 靈活的自定義頂部標題

實現功能: 1)自定義View標題欄佈局; 2)靈活的可以自己傳入型別,選擇所需要的控制元件來顯示隱藏 3)相對於我之前寫過的一篇,免繼承,可直接在佈局裡使用 4)直接可以在佈局控制元件裡設定屬性 老規矩,上幾張效果圖: 由效果圖可見,這個

Android webview隱藏頂部標題頂部空白margin

h5的頂部是這樣的 當我用webview載入的時候需要將更多這一片區域隱藏,同事更多下面這一塊距離頂部的margin也要隱藏(因為我將頂部隱藏掉後出現了大塊空白),已知h5頁面的程式碼是這樣:(谷歌瀏覽器按F12) 我們需要做的就是隱藏著兩個部分: 在webclient進行處理:

android顏色漸變的頂部標題

之前用的標題欄顏色都是純色的,最近美工說需要一個漸變色的標題欄,本來想著直接用一張圖片算了,後來想想,圖片行是行,但是android也是可以實現的 淘寶標題欄樣式 在res/drawable裡定義一個toolbar_bg.xml <shape x

Android頂部標題新增按鈕

<?xml version="1.0" encoding="utf-8"?>      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"          android:orientati

android 輸入法彈出鍵盤把listview頂上去,保留頂部標題位置不動

文章出處:http://blog.csdn.net/xingCome/article/details/51424724 只為記錄。 一:給listview 設定屬性 android:transcriptMode="normal"(必須) android:fastSc

AndroidActionBar

自android3.0來Action Bar就取代了OptionsMenu。於是就涉及了API的設定。    1)        設定<uses-sdk android:minSdkVersion="4"  android:targetSdkVersion="11"

Android Studio使用教程圖文

識別 由於 group 之前 而是 ces doc java代碼 風格 Android Studio是一款非常專業的Android集成開發環境工具,那麽,Android Studio怎麽用呢?針對不知道Android Studio怎麽使用的朋友們,本文就為大家圖文詳細介紹A

Android中的windowSoftInputMode屬性

stun -h oid 中文意思 ecif andro 標題 進行 模式 如何實現軟鍵盤不自動彈出,使用的方法是設置android:windowSoftInputMode屬性。那麽,這個屬性到底是幹什麽的,他有什麽作用呢?今天這篇文章,就是探索android:win

手機影音第四天,頂部標題的布局實現與本地視頻的搜索

頂部標題欄的布局實現與本地視頻的搜索前面講了下面的菜單布局與中間的fragmentLayout的布局與實現,今天就寫了頂部title的布局以及去搜索本地sd卡裏的視頻。 一、頂部布局實現 效果圖如下: 1、分析下: a、這個頂部布局是個LinearLayout布局 b、左

Android之build.prop屬性

lin logs generated reg dconf hostname product att make 註:本篇文章是基於MSD648項目(AndroidTV)的prop進行說明。 Android版本:4.4.4 內核版本:3.10.86 1.生成build.

aNDROID特效五種TOasT

smo android roi aid window mobile ongl ast andro aNDROID%E5%92%8CWINDOWsMOBILE http://music.baidu.com/songlist/495782919 http://music.b

AndroidAndroid六種布局

spec rec 默認 bottom ron ado 居中 右下角 控制 這篇就對LinearLayout、RelativeLayout、自定義ViewGroup、FrameLayout、TableLayout、AbsoluteLayout六種布局進行詳細的講解。 1