Android 標題欄(一)

       標題欄在每個應用中都有,有各種各樣的標題欄,今天我們就主要來說說標題欄怎麼做,主要內容涉及到自定義標題,ActionBar,Toolbar等知識。

自定義標題

       幾年前開發安卓是沒有統一的標題的,每一個頁面都需要自己來佈局標題,如果有多個頁面標題類似,往往就統一編寫出來一個佈局,統一管理和處理,這裏我們來看看怎麼編寫自定義佈局標題,不採用系統提供的,因爲有時候有些特定的或者特殊效果的標題,自定義比較方便。

       需要注意的是現在的應用基本上都從4.0開始支持,就算是低版本也有surpport包可以使用,因此在使用之前,給該頁面設置爲NoActionbar。

效果圖

       我們先來看一個圖片,這裏我們截取了易信中問一問的一個頁面來演示,界面是沉浸式的,這裏先不講怎麼實現沉浸式,下面會講到,真實的情況一般是不需要自定義的,界面如下:

這裏寫圖片描述

佈局

       首先我們新建一個title_layout.xml佈局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="56dp"
                android:background="@color/color_FA5864"
                android:orientation="vertical"
                tools:showIn="@layout/activity_custom_title">

    <ImageView
        android:id="@+id/back_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:src="@drawable/actionbar_white_back_icon"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@id/back_icon"
        android:textColor="@color/white"
        android:textSize="16sp"
        tools:text="@string/ask"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="18dp"
        android:src="@drawable/person_center"/>

</RelativeLayout>

       上面的佈局都很簡單,就是一個相對佈局,兩邊是圖標,中間一個標題,根據具體需求可以實現更爲複雜的效果,這裏我們來說說tools效果。

小技巧

tools:showIn="@layout/activity_custom_title"

因爲該title_layout是被其他佈局include引用使用的,因此你在當前界面預覽,只能預覽到當前實現的效果,而如果你添加了tools:showIn屬性,就可以在當前佈局預覽到放置到目標佈局後的效果。

tools:text=”@string/ask”
當我們在佈局時,有時可能需要設置文案來預覽實現效果,但是當正式提交時又需要刪除默認設置的文案,這裏可以使用tools:text來插入文案,這個只在編寫時有效果,正式提交時會刪除該屬性。

佈局引用

       在佈局完成後,就可以在目標佈局中include使用:

<include layout="@layout/title_layout"></include>

其他設置

       最後關掉當前的Actionbar,有以下幾種方式可以關閉:

  • onCreate中調用requestWindowFeature(Window.FEATURE_NO_TITLE);記住一定要在setContentView之前調用。至於爲什麼,你看看源碼就知道了。
  • 在AndroidManifest對對應的Activity設置style。style爲NoActionBar
  • 如果設置的style不是NoActionBar,則對使用的style複寫<item name="windowActionBar">false</item><item name="windowNoTitle">true</item>屬性

優缺點

       自定義很容易實現,他主要有哪些優缺點吶?

優點:

定製度高,靈活
容易實現比較複雜的佈局
容易實現自定義動畫效果

缺點

重複佈局,樣式多時通用性差
很多特定效果,代碼複雜
系統相比原生,優化比較少

ActionBar & Toolbar

       你可能在想爲什麼這裏要合在一起,不應該一個一個的講解嗎?這我們先看看他們出現的原因。

歷史沿革

       在系統早期沒有統一的標題設置,每個頁面就需要自己來實現標題,因此在Andriod 3.0版本,系統中引入了ActionBar來統一實現標題效果,並且對3.0以前的版本採用support包進行支持(其實現在基本上所有手機已經從4.0開始支持了,因此可以不需要考慮3.0以前的版本),ActionBar的出現,提供了全局統一的UI界面,並且提供了一致的操作效果,只要你是ActionBar進行實現的,都有同樣的效果。

       雖然ActionBar統一了很多東西,但是它也犧牲了靈活性,爲了實現某些效果還是需要採用自定義實現,尤其是一些炫酷的標題效果,google也認識到了這個問題,尤其是在當前界面不炫酷都沒有人用的情況下,google在Android L(5.0)版本提供了Toolbar,在L之前的版本採用support包來實現,Toolbar可以當做ActionBar來使用,並且提供了靈活性,因此ActionBar已經不怎麼建議使用了。由於Toolbar可以當前ActionBar來使用,說明兩者具有很多相同的東西,因此這裏放到一起來講解。

ActionBar的顯示與隱藏

ActionBar的顯示

       在3.0以上的版本,只要你的Activity實現了Theme.Holo主題,或者Theme.Holo的子主題,他默認就已經有ActionBar效果了。如果是其他主題,你可能需要調用requestWindowFeature(Window.FEATURE_ACTION_BAR)函數來顯示,或者對你使用的主題中的 windowActionBar屬性設置爲true,而3.0之前的版本(不用考慮3.0之前的版本)你需要讓你的Activity繼承自ActionBarActivity,並且設置主題爲Theme.AppCompat主題。

ActionBar的影藏

       在前面自定義的時候我們已經說了怎麼隱藏,這裏在來提一下,可以調用requestWindowFeature(Window.FEATURE_NO_TITLE)來隱藏,也可以對Activity設置NoActionBar主題進行隱藏,或者設置windowActionBar爲false,還可以在代碼中調用getActionBar().hide或者getSupportActionBar().hide()。這裏調用的函數不同是根據你繼承的Activity來區分的,如果你直接繼承的是Activity則調用getActionBar(),如果是support包中則調用getSupportActionBar()。

Toolbar的使用

       要使用Toolbar,首先要將默認出現的ActionBar隱藏,因此需要設置NoActionBar,或者設置windowActionBar爲false,之後在佈局中加入Toolbar節點。樣例如下,Activity引入的一個toolbar_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context="com.netease.study.ui.title.ToolbarActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="內容內容內容"/>


</LinearLayout>

       佈局完成後,在界面中find該View,將他設置到ActionBar,讓Activity將它當做ActionBar來處理。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_toolbar);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

       將find出來的Toolbar設置到ActionBar。就這麼簡單,之後所有的使用方式都跟之前的ActionBar一樣了。從佈局中也可以看出我們將Toolbar放置在線性佈局的頂部,其實它可以放置在任何位置,與ActionBar不一樣,ActionBar默認在頂部,狀態欄以下的位置。

設置屬性

       既然是標題欄,那肯定是有一些屬性可以進行設置的,那我們就來以此的設置一些屬性,這裏設置的屬性對於ActionBar,Toolbar(這裏的Toolbar是當做ActionBar來使用的,就是調用了setSupportActionBar(toolbar)函數)都實用。我們來看看一張圖片,先來認識一下ActionBar上的各個屬性:
這裏寫圖片描述

  1. 爲ActionBar圖標,一般爲應用圖標,不過現在很多應用已經不再顯示圖標了,包含它只是爲了品牌曝光和宣傳
  2. Action按鈕,點擊這些圖標可以做一系統響應
  3. Overflow按鈕,當前面的Action按鈕顯示不下,且配置了某些屬性時會顯示該按鈕

設置圖標

       可以採用如下的方式來設置應用圖標:

       1. 在AndroidManifest中的Application節點或者Activity節點設置logo屬性

但是要注意的是如果你的主題是Theme.Holo的,如果設置了logo屬性,默認是會顯示圖標的,但是如果你設置的是Theme.AppCompat,那恭喜你,默認不顯示,如果你想顯示怎麼辦代碼中調用。

       2.調用代碼來顯示

       如果配置中沒有設置logo屬性,我們需要代碼來控制,但是這裏也分爲兩種情況:

a.如果你的Activity是繼承自Activity的,那麼你可以直接調用getActionBar().setLogo()

b.如果你的Activity是繼承自AppCompatActivity的,那麼你需要如下的方式來進行設置,三個設置方式一個都不能少:

private void setLogo() {
    ActionBar actionBar = getSupportActionBar();
    actionBar.setLogo(R.drawable.logo);
    actionBar.setDisplayUseLogoEnabled(true);
    actionBar.setDisplayShowHomeEnabled(true);
}

       上面就是整個設置logo的方式,Android就是這麼的坑爹啊!不同的版本,不同的主題,不同的基類情況就完全不一樣了,這也是Android適配的一方面,全是坑,坑。

設置標題

       設置標題是比較簡單的,不會出上面的那些幺蛾子,主要有以下兩種方式來設置:

       1:在AndroidManifest的Activity設置label節點,但是要注意的是這裏只能設置主標題

       2:在代碼中設置,如果是繼承自Activity調用getActionBar().setTitle()來設置主標題,調用getActionBar().setSubTitle()來設置副標題。如果是繼承自AppCompatActivity,則需要調用getSupportActionBar來進行設置。

設置Action按鈕

       我們在上面的ActionBar圖中認識到了有Action按鈕。那怎麼添加Action按鈕吶?我們來實現如下圖的效果:

這裏寫圖片描述

       1:首先創建一個菜單佈局 action_menu.xml,放置到menu文件下:

<?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/search_icon"
        android:icon="@drawable/actionbar_search_dark_icon"
        android:title="@string/search"
        app:showAsAction="always">
    </item>

    <item
        android:id="@+id/plus"
        android:icon="@drawable/actionbar_plus_icon_normal"
        android:title="@string/more"
        app:showAsAction="always">
    </item>
</menu>

       菜單裏面包含兩個按鈕一個搜索,一個加號,每一個item就表示一個菜單,item裏面可以繼續嵌套menu,作爲該項item的子菜單。這裏我們來看看每一個item有哪些屬性需要設置:

  1. id標識該菜單
  2. icon 顯示圖標,如果在overflow則顯示title
  3. title 如果在overflow中不顯示icon,直接顯示title,如果在ActionBar長按顯示該title
  4. showAsAction標識顯示規則,重點看一下該屬性:

always: always永遠顯示ActionBar中,如果空間不夠則無法顯示
ifRoom: ifRoom表示有空間的時候顯示在ActionBar中,否則顯示在overflow中
never:never一直顯示在overflow中


同時還需要注意的是:如果你使用的support,也就是Theme爲Theme.AppCompat,需要聲明xmlns:app="http://schemas.android.com/apk/res-auto" app可以改成任何名稱,showAsAction前面用app來標識, 如果不是採用的support,也就是Theme爲Theme.Holo,前面用android來標識,否則所有菜單都默認顯示在overflow中

       2:代碼中加載菜單,需要複寫onCreateOptionsMenu函數

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

       經過上述兩步,菜單就已經顯示在ActionBar上面了。

響應Action按鈕

       顯示菜單後,需要響應點擊事件,怎麼來響應點擊事件?需要複寫onOptionsItemSelected函數:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.search_icon:
            Toast.makeText(this, "clicked", Toast.LENGTH_LONG).show();
            break;
        case R.id.plus:
            break;
    }
    return super.onOptionsItemSelected(item);
}

       在onOptionsItemSelected中根據id來進行響應。

       由於文章是在太長,因此將文章分成了兩篇,剩下的內容在Android 標題欄(二)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章