如果本文幫助到你蓖租,本人不勝榮幸,如果浪費了你的時間羊壹,本人深感抱歉蓖宦。
希望用最簡單的大白話來幫助那些像我一樣的人。如果有什么錯誤油猫,請一定指出稠茂,以免誤導(dǎo)大家、也誤導(dǎo)我情妖。
本文來自:http://www.reibang.com/users/320f9e8f7fc9/latest_articles
感謝您的關(guān)注睬关。
主題功能老早就想研究了,可是看了很多之后鲫售,發(fā)現(xiàn)想要很好的實現(xiàn)共螺,并沒有什么簡單的辦法。
但是如果要求不高情竹,實現(xiàn)起來還是挺簡單的藐不。
一起來看一下。
先說說簡單的實現(xiàn)步驟
- 在 styles.xml 中定義不同的主題風(fēng)格秦效;
- 在 attrs.xml 文件中雏蛮,定義自己的屬性;
- 在 layout 布局文件中阱州,使用 styles.xml 中定義的屬性挑秉;
- 在 Activity 中切換主題,就好了苔货。
然后來看每一步的詳細操作:
1. 在 styles.xml 中定義不同的主題風(fēng)格
也就是定義多種風(fēng)格的主題犀概,設(shè)置不同的顏色等。
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!--Toolbar的背景顏色-->
<item name="colorPrimary">@color/colorPrimary</item>
<!--StatusBar的顏色-->
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!--主標(biāo)題的字體顏色-->
<item name="android:textColorPrimary">@color/textColorPrimary</item>
<!--控制元件的默認狀態(tài)顏色-->
<item name="android:colorControlNormal">@color/colorControlNormal</item>
<!--控制元件在選中狀態(tài)的顏色-->
<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>
大多時候夜惭,系統(tǒng)自帶的屬性并不夠用姻灶,所以就需要自定義一些屬性,比如說上面的最后一個屬性诈茧。
自定義方法如下
2. 在 attrs.xml 文件中产喉,定義自己的屬性
在values文件夾下,新建attrs.xml文件,定義自己的屬性曾沈。
<resources>
<attr name="Text_bg_Color" format="color"/>
</resources>
3. 在 layout 布局文件中这嚣,使用 styles.xml 中定義的屬性
布局文件中,在需要改變色調(diào)的位置塞俱,設(shè)置相應(yīng)的屬性姐帚。
4. 最后一步,在 Activity 中切換主題
public class MainActivity extends AppCompatActivity {
/**
* recreate() 會使 Activity 重新刷新敛腌,所以 這個標(biāo)志必須是靜態(tài)的卧土。
*/
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
}
/**
* 根據(jù)標(biāo)志改變主題
*/
private void changeTheme() {
if (night) {
setTheme(R.style.AppThemeNight);
} else {
setTheme(R.style.AppTheme);
}
}
}
到此,就可以實現(xiàn)一個最基本的切換主題了像樊,這樣也是會有一個問題尤莺,也就是閃屏。
但是如果要求不是很高生棍,這也是可以滿足需求的颤霎。
此項目代碼:
https://github.com/Wing-Li/AndroidPractice/tree/master/ThemeChange
閃屏也是大家想盡各種辦法想要解決的一個問題。
在此寫下大家解決的思路涂滴。
目前思路是:
- 利用 setTheme(); 改變主題友酱;
- 用 recreate() 刷新當(dāng)前Activity,主題就改變了柔纵。
解決閃屏辦法:
不再使用 setTheme();
而是將當(dāng)前 Activity 上的每個控件缔杉,分別改成自己設(shè)定的顏色。
對搁料,沒錯或详,就是修改每個控件。
各種解決辦法郭计,也就是看使用什么辦法可以更方便的修改多個控件霸琴。
找到了兩個切換主題的框架,從源碼中很明顯的可以看出昭伸,他們都是把常用的基本控件重寫的一遍梧乘,而我們要使用這個框架的時候,也必須使用框架所提供的控件庐杨。
當(dāng)調(diào)用了切換主題的方法后选调,會遍歷使用的控件修改相應(yīng)的顏色,從而達到 不閃屏切換主題的效果灵份。
https://github.com/Bilibili/MagicaSakura
https://github.com/dersoncheng/MultipleTheme
<br />
如果是有多個主題仁堪,用框架實現(xiàn)還能接受,畢竟很麻煩各吨。
但是如果僅僅只是要實現(xiàn)夜間模式枝笨,就使用個框架還是不太舒服,而且必須要使用框架帶的基本控件揭蜒。
所以還是有一些其他的方式横浑,目的還是那句話:使用更好的方式修改多個控件的顏色。
這篇文章介紹的方法屉更,感覺不錯:知乎和簡書的夜間模式實現(xiàn)套路
前面都大同小異徙融,主要是修改顏色的那一段代碼。
將其項目提煉后瑰谜,只剩修與修改主題相關(guān)代碼:
https://github.com/Wing-Li/AndroidPractice/tree/master/SeamlessChangeTheme
<br />
好了欺冀,本文就分享到這里。
如果有什么更好的方式萨脑,請一定告知隐轩。