1楣富、使用Android Support Library修改uiMode來實現(xiàn)
修改uimode是修改Configuration凿掂,這種主題切換只限于黑白模式,沒有其他模式纹蝴,不需要大量定義主題庄萎。
由于Support Library在23.2.0(6.0)的版本中才添加了Theme.AppCompat.DayNight主題,所以依賴的版本必須是高于23.2.0的塘安,并且糠涛,這個特性支持的最低SDK版本為14(4.0),所以耙旦,需要兼容Android 4.0的設(shè)備,是不能使用這個特性的萝究。
1)添加依賴
compile 'com.android.support:appcompat-v7:25.1.0'
2)新建夜間模式資源文件夾
在res目錄下新建values-night文件夾免都,然后在此目錄下新建colors.xml文件在夜間模式下的應用的資源。當然也可以根據(jù)需要新建drawable-night,layout-night等后綴為-night的夜間資源文件夾帆竹。
我的values和values-night目錄下的colors.xml的內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<!--FIXME 2-->
<!--這個文件中的color是夜間模式下使用的-->
<resources>
<color name="colorPrimary">#35464e</color>
<color name="colorPrimaryDark">#212a2f</color>
<color name="colorAccent">#212a2f</color>
<color name="textColorPrimary">#616161</color>
<color name="viewBackground">#212a2f</color>
</resources>
3) 將activity繼承AppCompatActivity
public class MainActivity extends AppCompatActivity{}
4) 在Application中指定夜間模式绕娘,一般將當前主題保存到SharedPreferences中
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
//FIXME 4
boolean isNight = SpUtil.getNightModel(this);
if (isNight) {
//使用夜間模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
//不使用夜間模式
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
}
setDefaultNightMode()方法中參數(shù)解釋:
MODE_NIGHT_NO. Always use the day (light) theme(一直應用日間(light)主題).
MODE_NIGHT_YES. Always use the night (dark) theme(一直使用夜間(dark)主題).
MODE_NIGHT_AUTO. Changes between day/night based on the time of day(根據(jù)當前時間在day/night主題間切換).
MODE_NIGHT_FOLLOW_SYSTEM(默認選項).
This setting follows the system’s setting, which is essentially MODE_NIGHT_NO
(跟隨系統(tǒng),通常為MODE_NIGHT_NO).
注意:
為什么不直接設(shè)置為MODE_NIGHT_AUTO呢栽连?引用
因為使用MODE_NIGHT_AUTO需要請求坐標權(quán)限险领,獲取系統(tǒng)的位置。你肯定會說了秒紧,這尼瑪不是坑爹嗎绢陌?如果程序已經(jīng)授予了坐標權(quán)限(location permission)(如果你的target SDK為23或者更高,需要考慮運行時權(quán)限)熔恢,AppCompat會試著去獲取上次保存的坐標脐湾,根據(jù)坐標來計算日出與日落的時間。如果程序沒有位置權(quán)限或者LocationManager沒有存儲上次坐標的信息呢叙淌?系統(tǒng)或默認設(shè)置為早上6點鐘為日出秤掌,下午10點為日落。用戶調(diào)整系統(tǒng)時間鹰霍,當前的主題也會隨之改變闻鉴。如果我們不希望用戶在設(shè)定主題后,主題還會隨著時間改變,MODE_NIGHT_AUTO就不適用了茂洒。
代碼參考:
https://git.oschina.net/hcj/lerannightmode_support_lib.git
https://github.com/TonnyL/PaperPlane
2孟岛、使用activity中的setTheme方式實現(xiàn)
3、換膚框架
github上很多類似的換膚框架,其實現(xiàn)方式:
1)基于theme的內(nèi)部資源加載蚀苛,使用setTheme切換)在验,第二種方式相同。
2)利用View的Tag:
代表框架:AndroidChangeSkin堵未,通過View的Tag來存儲夜間模式的Drawable/Color引用
多套皮膚使用相同名稱加不同后綴來區(qū)分腋舌,假設(shè)文本顏色item_text_color有一套默認皮膚,一套綠色皮膚一套紅色皮膚渗蟹,則要定義三個資源item_text_color块饺,item_text_color_red,item_text_color_green雌芽。
優(yōu)點:Android支持度高
缺點:需要自定義Tag授艰;部分View的Tag被其他邏輯占用
舉例:
<TextView
android :layout_width="wrap_content"
android :layout_height="wrap_content"
android :tag="skin:item_text_color:textColor"
android :text="@string/hello_world"
android :textColor="@color/item_text_color"/>
3)自定義View(在setTheme后遍歷并立刻刷新View),自定義View來實現(xiàn)主題切換世落,在XML內(nèi)全部使用自定義的View淮腾,當需要切換主題時使用監(jiān)聽器或者eventbus來通知所有的view來切換其樣式。
代表框架:MultipleTheme
優(yōu)點:靈活性比較高屉佳,每類View都可以自己決定如何支持夜間模式
缺點:對代碼的侵入性較大谷朝,xml和java代碼都有不小的改動
4)動態(tài)資源替換
代表框架:AndroidSkinLoader
實現(xiàn)原理:
AndroidSkinLoader利用的是2.3節(jié)中談到的代理LayoutInflater的onCreateView過程來創(chuàng)建View的原理,在創(chuàng)建View的過程中將View的backgound/textColor等屬性的值取出武花,并與View一起存到列表內(nèi)圆凰,在切換皮膚時遍歷列表,通過對原始id/屬性值做轉(zhuǎn)化体箕,找到當前皮膚對應的資源id/屬性值专钉,刷新View。
優(yōu)點:對現(xiàn)有布局和java代碼影響比較小
缺點:皮膚文件在新的apk包內(nèi)累铅,框架需要單獨下載跃须,然后加載新的apk包來換膚。
舉例:
<TextView
android :id="@+id/detail_text"
android :layout_width="wrap_content"
android :layout_height="wrap_content"
android :lineSpacingExtra="6sp"
android :layout_margin="10dp"
skin :enable="true"
android :textSize="18sp"
android:textColor="@color/color_new_item_synopsis" />
參考:
http://blog.csdn.net/u013478336/article/details/52484322
http://blog.csdn.net/u013478336/article/details/53083054
QSkinLoader
一個支持多種場景的Android換膚框架娃兽』亓基本原理是通過代理LayoutInflater的View創(chuàng)建過程解析皮膚相關(guān)屬性(background/src/textColor等),將皮膚相關(guān)屬性設(shè)置到View的Tag內(nèi)换薄,在切換皮膚時尋找對應的皮膚來完成實時刷新動作玉雾。
優(yōu)勢:
- 代碼及XML侵入性小
- 功能完善(支持Activity/Dialog/懸浮窗/PopWindow/Fragment等)
- 無需重啟Activity
- 支持自定義屬性換膚、同時支持資源內(nèi)換膚和獨立資源包(下載后換膚)等優(yōu)點
詳細介紹:
http://blog.csdn.net/u013478336/article/details/53083054