Android自定義TitleBar/ActionBar

一開始我便很困惑,TitleBar和ActionBar是什麼關係?
我們知道:
ActionBar是在android3.3之後推出使用的

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"                 

這意味着TitleBar似乎消失了,取而代之的是ActionBar。不過,既然是ActionBar,那麼就必然支持Action事件,同理可知TitleBar只顯示圖片和文字,不支持事件的,所以,從某種意義上來說,可以認爲ActionBar是TitleBar的升級 。

對於android3.3自定義標題欄流程如下:

一、自定義標題欄顏色和高度

直接在Activity的屬性中定義即可。

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Light">
        <item name="android:windowTitleBackgroundStyle">@style/settingsTitleBg</item>
        <item name="android:windowTitleSize">40dp</item>
    </style>

    <style name="settingsTitleBg">
        <item name="android:background">#0000ff</item>
    </style>

定義標題欄背景色需要使用到Android:windowTitleBackgroundStyle屬性,給這個屬性指定一個style,這裏爲settingsTitleBg,然後在其中指定android:background的顏色即可。
指定標題欄高度只需要修改android:windowTitleSize的值即可。

二、自定義標題欄佈局

調用如下方法即可:

    public static void getCustomTitle(Activity activity, String title) {
        mActivity = activity;
        mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        mActivity.setContentView(R.layout.custom_title);
        mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
                R.layout.custom_title);

        TextView textView = (TextView) activity.findViewById(R.id.title_content_text);
        textView.setText(title);
        Button titleBackBtn = (Button) activity.findViewById(R.id.title_back_button);
        titleBackBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Log.d("Title back","key down");
                mActivity.finish();
            }
        });
    }

這個方法中使用到了R.layout.custom_title佈局,這個佈局便是可以隨意自定義的佈局文件,這裏指定的佈局文件如下:
custom_title.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <Button
        android:layout_marginLeft="10dp"
        android:layout_gravity="center_vertical"
        android:background="@drawable/back"
        android:id="@+id/title_back_button"
        android:layout_width="20dp"
        android:layout_height="20dp" />
    <TextView
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:id="@+id/title_content_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize="20sp"
        android:textColor="#FFFFFF"
        />
</LinearLayout>

完成後在setContentView之前調用getCustomTitle方法即可完成自定義標題欄的工作。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//設置全屏
        CustomTitle.getCustomTitle(this, "系統信息");
        setContentView(R.layout.activity_main);

CustomTitle方法的第一個參數就是當前的Activity,第二個參數是標題欄的標題。CustomTitle是我定義的一個類,其中只有getCustomTitle一個靜態方法。
至此,效果如下:
這裏寫圖片描述
這裏寫圖片描述

三、Holo主題下自定義標題欄
現在,如果將主題從android:Theme.Light改爲android:Theme.Holo.Light,那麼程序會報錯,如下:

 Caused by: android.util.AndroidRuntimeException: You cannot combine custom titles with other title features

這個時候,只需要在style中把ActionBar關掉就好了。

    <style name="AppTheme" parent="android:Theme.Holo.Light">
        <item name="android:windowTitleBackgroundStyle">@style/settingsTitleBg</item>
        <item name="android:windowTitleSize">40dp</item>
        <item name="android:windowActionBar">false</item>
    </style>

這樣可以自定義標題欄,但是界面呈現出來會有閃爍,也就是默認的ActionBar會先顯示出來,然後纔是你自定義的標題欄,一次,在Holo主題下,這種方法不可取。

自定義ActionBar

我們也可以傳入自定義的佈局文件給ActionBar,方法如下:

getActionBar().setCustomView(R.layout.custom_title);

R.layout.custom_title就是我們傳入的佈局文件。我們也可以通過findViewById來爲各個View設置監聽器。但這種方式也無法便面閃爍原來ActionBar的問題,這非常討厭。

解決自定義ActionBar閃爍原來ActionBar的問題

從原題產生的原因分析,應該是設置主題的時候造成的,主題中如果有ActionBar,那麼ActionBar的繪製在Activity的佈局文件繪製之前,因此,會有閃爍的問題出現。因此,我的解決方法是乾脆不用ActionBar,找一個沒有ActionBar的Theme,比如@android:style/Theme.Holo.Light.NoActionBar.Fullscreen。然後,使用ToolBar代替,ToolBar在Activity的佈局文件中,他可以放置在佈局文件的任意位置,就像一個普通的View組件一樣,因此,它的繪製和Activity內容的繪製是一起的。ToolBar使用如下:

    <Toolbar
        android:id="@+id/toolbar"
        android:title="系統設置"
        android:navigationIcon="@drawable/back"
        android:background="#0000ff"
        android:layout_width="match_parent"
        android:layout_height="40dp"></Toolbar>

由於ToolBar在Activity的佈局文件中使用,因此非常有靈活性。這裏設置了title-標題,還有導航icon,我們還可以給導航按鈕這隻事件監聽器,比如讓Acitivity結束運行:

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章