Android實現(xiàn)夜間模式的方法(二)

該文章接上篇 Android實現(xiàn)夜間模式的方法(一)

三.夜間模式的實現(xiàn)方案——單純夜間模式

1.通過切換主題實現(xiàn)

這是通過創(chuàng)建一套夜間模式的主題掺炭,然后在設(shè)置時進行切換驹尼。在Activity中有一個方法叫setTheme(),可以設(shè)置Activity的Theme夕吻,當(dāng)然Application類中也有相同的方法乌逐,也可以在Application中設(shè)置當(dāng)前應(yīng)用的Theme擎椰。

首先在attrs.xml中逻住,為需要隨theme變化的內(nèi)容設(shè)置自定義屬性

<resources>
    <attr name="textColor" format="color|reference" />
    <attr name="mainBackground" format="color|reference" />
</resources>

然后定義自己的夜間模式的風(fēng)格钟哥,示例如下:

<!-- 夜間 -->
    <style name="ThemeNight" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="mainBackground">#000000</item>
        <item name="textColor">#ffffff</item>
    </style>

接下來只要在布局文件中使用對應(yīng)的值迎献,通過?attr/屬性名的方法就可以實現(xiàn)根據(jù)風(fēng)格設(shè)置不同的屬性的目的瞎访。

這種方法是是Android官方推薦的方式,較為簡單常用但這種方式有一些不足吁恍,規(guī)模較大的應(yīng)用扒秸,需要隨theme變化的屬性會很多,都需要逐一定義冀瓦。

2.通過修改資源id映射方式實現(xiàn)

這種方法的思路是通過id獲取資源時伴奥,先將其轉(zhuǎn)換為夜間模式對應(yīng)id,再通過Resources來獲取對應(yīng)的資源翼闽。

public static Drawable getDrawable(Context context, int id) {
    return context.getResources().getDrawable(getResId(id));
}

public static int getResId(int defaultResId) {
    if (!isNightMode()) {
        return defaultResId;
    }
    if (sResourceMap == null) {
        buildResourceMap();
    }
    int themedResId = sResourceMap.get(defaultResId);
    return themedResId == 0 ? defaultResId : themedResId;
}

可以通過HashMap將白天模式的resId和夜間模式的resId來一一對應(yīng)起來

private static void buildResourceMap() {
    sResourceMap = new SparseIntArray();
    sResourceMap.put(R.drawable.common_background, R.drawable.common_background_night);
    // ...
}

3.通過使用系統(tǒng)提供的夜間模式主題實現(xiàn)

在Support Library 23.2.0添加了一條新的變化 AppCompat 現(xiàn)在有個新的主題:Theme.AppCompat.DayNight. 這個主題可以根據(jù)系統(tǒng)時間切換 Theme.AppCompat(暗色) 和 Theme.AppCompat.Light(亮色) 兩種主題拾徙。這將會對應(yīng)用的用戶特別有用,特別是閱讀類應(yīng)用感局。需要注意的是尼啡,這個特性只支持 API v14 及以上的 Android 設(shè)備,在 API v14 以下的設(shè)備則會默認(rèn)使用亮色的主題询微。而且activity必須繼承要AppCompatActivity崖瞭。

首先得先在你的 style.xml 文件里,讓主題繼承 DayNight 主題撑毛,例如:

<style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">

然后在 Application 添加一個靜態(tài)代碼塊來進行初始化全局設(shè)置:

static {
    AppCompatDelegate.setDefaultNightMode(
        AppCompatDelegate.MODE_NIGHT_AUTO); 
}
然后使用自定義資源书聚,只需要在 res 目錄下創(chuàng)建對應(yīng)的 values-night 文件夾并創(chuàng)建對應(yīng)的 themes.xml 文件,重新定義夜間模式的主題風(fēng)格,例如:
res/values-night/colors.xml
<color name="colorPrimary">#201D45</color>
<color name="colorPrimaryDark">#201D45</color>

同理其他資源你只需要在文件的末尾添加 -night 系統(tǒng)就會自動加載對應(yīng)的文件了雌续。
實現(xiàn)的效果如下示例:

效果示例.png

4.通過使用開源框架實現(xiàn)——Android-Skin-Loader

Android-Skin-Loader是一個通過動態(tài)加載本地皮膚包進行換膚的皮膚框架
使用方法:

  1. 在Application中進行初始化
public class SkinApplication extends Application {
   public void onCreate() {
        super.onCreate();
        // Must call init first 
        SkinManager.getInstance().init(this);
        SkinManager.getInstance().load();
    }
}
  1. 在布局文件中標(biāo)識需要換膚的View
    xmlns:skin="http://schemas.android.com/android/skin"
  2. 繼承BaseActivity或者BaseFragmentActivity作為BaseActivity進行開發(fā)
  3. 從.skin文件中設(shè)置皮膚
SkinManager.getInstance().load(skin.getAbsolutePath(),
                new ILoaderListener() {
//重寫該類下的方法
});

皮膚包(后綴名為.skin)的本質(zhì)是一個apk文件斩个,該apk文件不包含代碼,只包含資源文件

在皮膚包工程中(示例工程為skin/BlackFantacy)添加需要換膚的同名的資源文件驯杜,直接編譯生成apk文件萨驶,再更改后綴名為.skin即可(防止用戶點擊安裝)

使用gradle的同學(xué),buildandroid-skin-loader-skin工程后即可在skin-package目錄下取皮膚包(修改腳本中def skinName = "BlackFantacy.skin"換成自己想要的皮膚名)

Load包下的兩個類
SkinInflaterFactory: 搜集需要的換膚的控件艇肴,并創(chuàng)建相應(yīng)的換膚控件腔呜,并把需要換膚的空間及其相應(yīng)支持的換膚屬性存儲起來。

SkinManager: 其內(nèi)部通過反射調(diào)用AssetManager.addAssetPath()把外部的皮膚資源加載到AssetManager中再悼,并通過該AssetManager創(chuàng)建相應(yīng)的Resource核畴。當(dāng)執(zhí)行換膚操作的時候,就可以設(shè)置需要換膚View的相關(guān)屬性為Resource中相應(yīng)的資源冲九。

5.通過使用開源框架實現(xiàn)——NightModel

NightModel是個方便切換夜間模式的庫谤草,利用官方夜間模式,同時不用重啟Activity
使用方法
1.在appication中初始化
2.只需要在需要刷新的activity中調(diào)用attach莺奸、detach方法丑孩。其它activity不需要調(diào)用此方法
3.切換時調(diào)用appleyDayModel\appleyNightModel進行夜間模式切換

使用要求
官方包support appcompat 23.2.0 或以上版本
activity 需要繼承自 AppCompatActivity
應(yīng)用按照官方的夜間模式實現(xiàn)

6.通過使用開源框架實現(xiàn)——MultipleTheme

MultipleTheme是一個支持無縫換膚/夜間模式的Android框架,配合theme和換膚控件框架可以做到無縫切換換膚(無需重啟應(yīng)用和當(dāng)前頁面)灭贷。需要在換膚/切換夜間模式的界面只需要使用框架里的自封裝控件温学,其他界面的控件使用原生android控件即可。

第一步:在項目的attr.xml聲明自定義屬性(各種模式都會用到的屬性)
第二步:在項目的style.xml指定各種模式主題下的自定義屬性值
第三步:在頁面布局文件里使用自定義屬性值
第四步:在基類的onCreate方法里添加切換主題模式的邏輯代碼
第五步:調(diào)用工具類方法切換主題模式
第六步:針對切換主題模式時需要立即更新頁面ui的頁面甚疟,需要使用框架里的封裝控件

MultipleTheme的內(nèi)部代碼1.png
MultipleTheme的內(nèi)部代碼2.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仗岖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子览妖,更是在濱河造成了極大的恐慌轧拄,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讽膏,死亡現(xiàn)場離奇詭異檩电,居然都是意外死亡,警方通過查閱死者的電腦和手機府树,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門俐末,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挺尾,你說我怎么就攤上這事鹅搪。” “怎么了遭铺?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵丽柿,是天一觀的道長恢准。 經(jīng)常有香客問我,道長甫题,這世上最難降的妖魔是什么馁筐? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮坠非,結(jié)果婚禮上敏沉,老公的妹妹穿的比我還像新娘。我一直安慰自己炎码,他們只是感情好盟迟,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著潦闲,像睡著了一般攒菠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歉闰,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天辖众,我揣著相機與錄音,去河邊找鬼和敬。 笑死凹炸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的昼弟。 我是一名探鬼主播啤它,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼私杜!你這毒婦竟也來了蚕键?” 一聲冷哼從身側(cè)響起救欧,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤衰粹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笆怠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铝耻,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年蹬刷,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓢捉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡办成,死狀恐怖泡态,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情迂卢,我是刑警寧澤某弦,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布桐汤,位于F島的核電站,受9級特大地震影響靶壮,放射性物質(zhì)發(fā)生泄漏怔毛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一腾降、第九天 我趴在偏房一處隱蔽的房頂上張望拣度。 院中可真熱鬧,春花似錦螃壤、人聲如沸抗果。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窖张。三九已至,卻和暖如春蚁滋,著一層夾襖步出監(jiān)牢的瞬間宿接,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工辕录, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留睦霎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓走诞,卻偏偏與公主長得像副女,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蚣旱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容