安卓開發之樣式和主題的使用與夜間/白天模式的動態轉換

cxmscb發表於2016-08-17

一、樣式(Style)

在寫佈局時,當多個檢視有不少相同的屬性時,可以將這些相同的屬性放在一起在styles.xml中自定義為一個style。在佈局檔案中 使用style=”@style/style_name”統一引用。

可以把樣式理解為多個檢視屬性的集合。

一、樣式的作用

複用檢視標籤屬性,防止佈局檔案累贅。

二、樣式的目標

針對視窗中的某些檢視。

三、樣式的定義與繼承

在styles.xml定義樣式:

<resources>

    <style name="textstyle">  
        <item name="android:layout_width">fill_parent</item>  
        <item name="android:gravity">center</item> 
    </style>  

    <style name="subtextstyle" parent="textstyle">  
        <item name="android:layout_width">wrap_content</item>  
        <item name="android:textColor">#000000</item>  
    </style>  

<resources>

在佈局檔案中引用:

<TextView
    style="@style/subtextstyle"
    android:text="@string/hello" />
  1. 其中name為我們定義的樣式名字,便於我們對樣式的引用,parent為對父樣式的繼承,可以將父樣式的標籤屬性繼承過來,可以在繼承中對標籤屬性覆寫。

  2. 我們也可以引用/繼承Android系統已定義的一些系統樣式:style=”@android:style/xxxx”

  3. 樣式的標籤屬性的優先順序:就近原則

二、主題(Theme)

主題的本質也是樣式style,作用也是複用檢視的標籤屬性,在styles.xml中定義,可繼承/覆寫,但是在manifest.xml中引用。

一、主題的目標

針對整個應用Application或某個Activity的介面

二、主題的定義與使用示例:

在styles.xml定義主題:

<style name="CustomTheme" parent="android:Theme.Light">
    <item name="android:windowBackground">#FFFFFF</item>
</style>

在manifest.xml中引用主題

<application android:theme="@style/CustomTheme">
...
<activity android:theme="@style/CustomTheme">
...
  1. 主題中的標籤屬性的優先順序:就近原則
    (視窗檢視的屬性>視窗中的檢視style>activity中的主題的標籤屬性>application中的主題的標籤屬性)

  2. 系統常用主題:

    • @android:style/Theme.Light.NoTitleBar : 沒有標題欄
    • @android:style/Theme.Light.NoTitleBar.Fullscreen : 全屏
    • @android:style/Theme.Dialog : 對話方塊
  3. 使用程式碼設定Activity主題:this.setTheme(R.style.CustomTheme)

三、使用主題進行夜間/白天模式的動態轉換

主要通過對Activity主題的設定來實現

效果圖:

這裡寫圖片描述

一、設定主題的屬性

根據主題的不同,設定不同屬性給佈局檔案的檢視來使用。

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="titleBarColor" format="color" />
    <attr name="textColor" format="color" />
    <attr name="textBackground" format="color" />
    <attr name="imageValue" format="reference"/>

</resources>

二、設計兩個主題

一個白天,一個黑夜,為防止Activity的主題被覆蓋,使這兩個主題繼承原主題:

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>


    <style name="DayTheme" parent="AppTheme">
        <item name="titleBarColor">@color/day_titlebar</item>
        <item name="textColor">@color/day_text</item>
        <item name="textBackground">@android:color/white</item>
        <item name="imageValue">@drawable/night</item>
    </style>

    <style name="NightTheme" parent="AppTheme" >
        <item name="titleBarColor">@color/night_titlebar</item>
        <item name="textColor">@android:color/white</item>
        <item name="textBackground">@android:color/black</item>
        <item name="imageValue">@drawable/day</item>
    </style>

三、在Activity中進行邏輯判斷並載入主題

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(MyApplication.appConfig.isNighTheme()){
        this.setTheme(R.style.NightTheme);
        isNight =  true;
    }else{
        this.setTheme(R.style.DayTheme);
        isNight = false;
    }
    setContentView(R.layout.activity_main);

}

四、實現更換主題並帶原意圖重啟Activity

通過使用動畫來重啟Activity防止閃爍

public void changeTheme(View view) {

    //Toast.makeText(this,"123",Toast.LENGTH_SHORT).show();

    if(isNight){
        MyApplication.appConfig.setNightTheme(false);
    }else{
        MyApplication.appConfig.setNightTheme(true);
    }

    Intent intent = getIntent();
    overridePendingTransition(R.anim.in_anim, R.anim.out_anim);
    startActivity(intent);

    finish();




}

完整程式碼:

Github

相關文章