android自动切换暗色,超实用!Android 深色模式适配(可定时开启的APP内主题切换管理工具)...
前言
前面分享了一篇“黑白化主題”的文,主要適用場景是不久就要到來的“清明”等時節(jié)或者是其他的國家公祭日什么的(一名成熟的程序員,要學會自己提產(chǎn)品需求)。
今天分享的是一個Android 深色模式適配,可定時開啟的APP內(nèi)主題切換管理工具。
今天想著將深色模式的管理整合到一個文件當中,想到自己深色模式適配的文章上,結(jié)果才發(fā)現(xiàn)我原來沒有寫這篇文章……為啥我腦子里記得我好像寫過的呢,啊,怕是在腦海里曾經(jīng)構(gòu)思過,然后腦子騙自己以為寫了。
閑話少說,直接開碼。
深色模式適配
這個比較簡單,首先改一下style,用DayNight的
然后在資源文件夾里,加一個文件夾values-night,里面放什么呢,就是你對應深色模式下的顏色配置文件colors.xml
其他圖片文件資源其實也一樣,建立一個mipmap-night文件夾放進去就好了。
APP主題切換工具
這個我自己上代碼了
/**
* 深色模式工具
*
* @author D10NG
* @date on 2020/4/27 2:03 PM
*/
class NightModeUtils constructor(context: Context) {
private val mSpf = context.getSharedPreferences("config_data", Context.MODE_PRIVATE)
companion object {
@Volatile
private var INSTANCE: NightModeUtils? = null
@JvmStatic
fun getInstance(context: Context) : NightModeUtils =
INSTANCE ?: synchronized(this) {
INSTANCE ?: NightModeUtils(context).also {
INSTANCE = it
}
}
private const val SPF_THEME_MODE = "theme_mode"
private const val SPF_THEME_TIMER = "theme_timer"
}
/** 獲取設置 */
private fun getSpfThemeMode() : Int = mSpf.getInt(SPF_THEME_MODE, ThemeMode.MODE_FOLLOW_SYSTEM.intValue)
/** 設置 */
private fun setSpfThemeMode(mode: Int) {
mSpf.edit().putInt(SPF_THEME_MODE, mode).apply()
}
/** 獲取時間設置 */
private fun getSpfThemeTimer() : String = mSpf.getString(SPF_THEME_TIMER, null)?: "18:00~08:00"
/** 設置時間 */
private fun setSpfThemeTimer(timer: String) {
mSpf.edit().putString(SPF_THEME_TIMER, timer).apply()
}
/** 獲取設置好的ThemeMode */
fun getThemeMode(): ThemeMode = ThemeMode.parseOfInt(getSpfThemeMode())
/** 設置模式 */
fun setThemeMode(mode: ThemeMode) {
setSpfThemeMode(mode.intValue)
}
/** 獲取設置好的定時時間 */
fun getThemeTime(): ThemeTime {
val timeStr = getSpfThemeTimer()
return ThemeTime(
beginHour = timeStr.split("~")[0].split(":")[0].toInt(),
beginMinute = timeStr.split("~")[0].split(":")[1].toInt(),
endHour = timeStr.split("~")[1].split(":")[0].toInt(),
endMinute = timeStr.split("~")[1].split(":")[1].toInt()
)
}
/** 設置定時時間 */
fun setThemeTime(time: ThemeTime) {
setSpfThemeTimer(time.toTimerString())
}
/**
* 應用存儲的設置
*/
fun applySetting() {
// 檢查主題
val themeModeInt = getSpfThemeMode()
val themeMode = ThemeMode.parseOfInt(themeModeInt)
AppCompatDelegate.setDefaultNightMode(when(themeMode) {
ThemeMode.MODE_ALWAYS_ON -> AppCompatDelegate.MODE_NIGHT_YES
ThemeMode.MODE_ALWAYS_OFF -> AppCompatDelegate.MODE_NIGHT_NO
ThemeMode.MODE_FOLLOW_SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
else -> {
val time = getThemeTime()
val startTime = time.startTime.replace(":", ".").toFloat()
val stopTime = time.stopTime.replace(":", ".").toFloat()
val curTime = DateUtils.getCurDateStr("HH.mm").toFloat()
if (stopTime > startTime) {
// 結(jié)束時間和開始時間都在同一天
if (curTime > startTime && curTime < stopTime) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
} else {
// 結(jié)束時間在開始時間的后一天
if (curTime > startTime || curTime < stopTime) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
}
}
})
}
}
/**
* 主題設置時間
*/
data class ThemeTime(
// 開始小時
val beginHour: Int,
// 開始分鐘
val beginMinute: Int,
// 結(jié)束小時
val endHour: Int,
// 結(jié)束分鐘
val endMinute: Int,
// 開始時間
var startTime: String = "00:00",
// 結(jié)束時間
var stopTime: String = "00:00"
) : Serializable {
init {
startTime = "${upTo2String(beginHour)}:${upTo2String(beginMinute)}"
stopTime = "${upTo2String(endHour)}:${upTo2String(endMinute)}"
}
fun toTimerString() : String = "$startTime~$stopTime"
// 保存成長度為2的字符串
private fun upTo2String(value: Int): String {
val valueStr = "$value"
val result = StringBuilder()
if (valueStr.length < 2) {
for (i in 0 until 2 - valueStr.length) {
result.append("0")
}
}
result.append(valueStr)
return result.toString().substring(result.length - 2)
}
}
還有一個主題列表
/**
* 主題開啟模式
* @author D10NG
* @date on 2020/2/26 10:02 AM
*/
enum class ThemeMode(val intValue: Int, val stringValueId: Int) {
MODE_ALWAYS_ON(0, R.string.theme_mode_0),
MODE_ALWAYS_OFF(1, R.string.theme_mode_1),
MODE_FOLLOW_SYSTEM(2, R.string.theme_mode_2),
MODE_TIMER(3, R.string.theme_mode_3),;
companion object {
@JvmStatic
fun parseOfString(context: Context, String: String): ThemeMode {
return when(String) {
context.resources.getString(MODE_ALWAYS_ON.stringValueId) -> MODE_ALWAYS_ON
context.resources.getString(MODE_ALWAYS_OFF.stringValueId) -> MODE_ALWAYS_OFF
context.resources.getString(MODE_TIMER.stringValueId) -> MODE_TIMER
else -> MODE_FOLLOW_SYSTEM
}
}
@JvmStatic
fun parseOfInt(intValue: Int) : ThemeMode {
return when(intValue) {
MODE_ALWAYS_ON.intValue -> MODE_ALWAYS_ON
MODE_ALWAYS_OFF.intValue -> MODE_ALWAYS_OFF
MODE_TIMER.intValue -> MODE_TIMER
else -> MODE_FOLLOW_SYSTEM
}
}
}
}
字符串在這里
一直開啟
一直關(guān)閉
跟隨系統(tǒng)設置
定時開啟
使用方法
首先在Aplication的onCreate中啟動保存設置
override fun onCreate() {
super.onCreate()
// 應用主題設置
NightModeUtils.getInstance(this).applySetting()
}
然后在你的Activity(最好有BaseActivity)中的onResume中同樣加入啟動設置
override fun onResume() {
super.onResume()
NightModeUtils.getInstance(this).applySetting()
}
以上就能保證頁面能順利切換主題了。
設置主題
NightModeUtils.getInstance(this).setThemeMode(ThemeMode.MODE_TIMER)
設置定時
val time = ThemeTime(
endHour = 18,
endMinute = 0,
beginHour = 8,
beginMinute = 0
)
NightModeUtils.getInstance(this).setThemeTime(time)
應用設置
NightModeUtils.getInstance(this).applySetting()
大功告成
照著走就沒毛病了。
最后
我覺得有一個朋友說的話很對:Android學習,我們要學習的東西不僅僅只有表面的 技術(shù),還要深入底層,弄明白下面的 原理,只有這樣,我們才能夠提高自己的競爭力,在當今這個競爭激烈的世界里立足。
我把自己這段時間整理的Android最重要最熱門的學習方向資料放在了我的GitHub(點擊此處可查看),里面還有不同方向的自學編程路線、面試題集合/面經(jīng)、及系列技術(shù)文章等。
歡迎大家一起學習和探討。
總結(jié)
以上是生活随笔為你收集整理的android自动切换暗色,超实用!Android 深色模式适配(可定时开启的APP内主题切换管理工具)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Chainer Chemistry |
- 下一篇: conda 多环境切换