Android夜間模式(多主題)探索

JanisNoguer 8年前發布 | 4K 次閱讀 安卓開發 Android開發 移動開發

主題功能老早就想研究了,可是看了很多之后,發現想要很好的實現,并沒有什么簡單的辦法。

但是如果要求不高,實現起來還是挺簡單的。

先說說簡單的實現步驟

  1. 在 styles.xml 中定義不同的主題風格;
  2. 在 attrs.xml 文件中,定義自己的屬性;
  3. 在 layout 布局文件中,使用 styles.xml 中定義的屬性;
  4. 在 Activity 中切換主題,就好了。

然后來看每一步的詳細操作:

1. 在 styles.xml 中定義不同的主題風格

也就是定義多種風格的主題,設置不同的顏色等。

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <!--Toolbar的背景顏色-->
        <item name="colorPrimary">@color/colorPrimary</item>
        <!--StatusBar的顏色-->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <!--主標題的字體顏色-->
        <item name="android:textColorPrimary">@color/textColorPrimary</item>
        <!--控制元件的默認狀態顏色-->
        <item name="android:colorControlNormal">@color/colorControlNormal</item>
        <!--控制元件在選中狀態的顏色-->
        <item name="colorAccent">@color/colorAccent</item>
        <!--Activity的背景顏色-->
        <item name="android:windowBackground">@color/windowBackground</item>
        <!--自定義的屬性-->
        <item name="Text_bg_Color">@color/Text_bg_Color</item>
    </style>

    <style name="AppThemeNight" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/NcolorPrimary</item>
        <item name="colorPrimaryDark">@color/NcolorPrimaryDark</item>
        <item name="android:textColorPrimary">@color/NtextColorPrimary</item>
        <item name="android:colorControlNormal">@color/NcolorControlNormal</item>
        <item name="colorAccent">@color/NcolorAccent</item>
        <item name="android:windowBackground">@color/NwindowBackground</item>
        <item name="Text_bg_Color">@color/NText_bg_Color</item>
    </style>
</resources>

大多時候,系統自帶的屬性并不夠用,所以就需要自定義一些屬性,比如說上面的最后一個屬性。

自定義方法如下

2. 在 attrs.xml 文件中,定義自己的屬性

在values文件夾下,新建attrs.xml文件,定義自己的屬性。

<resources>
    <attr name="Text_bg_Color" format="color"/>
</resources>

3. 在 layout 布局文件中,使用 styles.xml 中定義的屬性

布局文件中,在需要改變色調的位置,設置相應的屬性。

布局文件

4. 最后一步,在 Activity 中切換主題

public class MainActivity extends AppCompatActivity {

    /**
     * recreate() 會使 Activity 重新刷新,所以 這個標志必須是靜態的。
     */
    private static boolean night = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        changeTheme();
        setContentView(R.layout.activity_main);

        findViewById(R.id.email_sign_in_button).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                change();
            }
        });
    }

    private void change() {
        night = !night;
        changeTheme();
        recreate();// 重啟 Activity
    }

    /**
     * 根據標志改變主題
     */
    private void changeTheme() {
        if (night) {
            setTheme(R.style.AppThemeNight);
        } else {
            setTheme(R.style.AppTheme);
        }
    }
}

到此,就可以實現一個最基本的切換主題了,這樣也是會有一個問題,也就是閃屏。

但是如果要求不是很高,這也是可以滿足需求的。

閃屏也是大家想盡各種辦法想要解決的一個問題。

在此寫下大家解決的思路。

目前思路是:

  1. 利用 setTheme(); 改變主題;
  2. 用 recreate() 刷新當前Activity,主題就改變了。

解決閃屏辦法:

不再使用 setTheme();

而是將當前 Activity 上的每個控件,分別改成自己設定的顏色。

對,沒錯,就是修改每個控件。

各種解決辦法,也就是看使用什么辦法可以更方便的修改多個控件。

找到了兩個切換主題的框架,從源碼中很明顯的可以看出,他們都是把常用的基本控件重寫的一遍,而我們要使用這個框架的時候,也必須使用框架所提供的控件。

當調用了切換主題的方法后,會遍歷使用的控件修改相應的顏色,從而達到 不閃屏切換主題的效果。

MagicaSakura

MultipleTheme

如果是有多個主題,用框架實現還能接受,畢竟很麻煩。

但是如果僅僅只是要實現夜間模式,就使用個框架還是不太舒服,而且必須要使用框架帶的基本控件。

所以還是有一些其他的方式,目的還是那句話:使用更好的方式修改多個控件的顏色。

前面都大同小異,主要是修改顏色的那一段代碼。

將其項目提煉后,只剩修與修改主題相關代碼:

 

 

來自: http://www.jianshu.com/users/320f9e8f7fc9/latest_articles

 

 

 本文由用戶 JanisNoguer 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!