android自动切换暗色,超实用!Android 深色模式适配(可定时开启的APP内主题切换管理工具)...
前言
前面分享了一篇“黑白化主題”的文,主要適用場(chǎng)景是不久就要到來(lái)的“清明”等時(shí)節(jié)或者是其他的國(guó)家公祭日什么的(一名成熟的程序員,要學(xué)會(huì)自己提產(chǎn)品需求)。
今天分享的是一個(gè)Android 深色模式適配,可定時(shí)開(kāi)啟的APP內(nèi)主題切換管理工具。
今天想著將深色模式的管理整合到一個(gè)文件當(dāng)中,想到自己深色模式適配的文章上,結(jié)果才發(fā)現(xiàn)我原來(lái)沒(méi)有寫(xiě)這篇文章……為啥我腦子里記得我好像寫(xiě)過(guò)的呢,啊,怕是在腦海里曾經(jīng)構(gòu)思過(guò),然后腦子騙自己以為寫(xiě)了。
閑話(huà)少說(shuō),直接開(kāi)碼。
深色模式適配
這個(gè)比較簡(jiǎn)單,首先改一下style,用DayNight的
然后在資源文件夾里,加一個(gè)文件夾values-night,里面放什么呢,就是你對(duì)應(yīng)深色模式下的顏色配置文件colors.xml
其他圖片文件資源其實(shí)也一樣,建立一個(gè)mipmap-night文件夾放進(jìn)去就好了。
APP主題切換工具
這個(gè)我自己上代碼了
/**
* 深色模式工具
*
* @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"
}
/** 獲取設(shè)置 */
private fun getSpfThemeMode() : Int = mSpf.getInt(SPF_THEME_MODE, ThemeMode.MODE_FOLLOW_SYSTEM.intValue)
/** 設(shè)置 */
private fun setSpfThemeMode(mode: Int) {
mSpf.edit().putInt(SPF_THEME_MODE, mode).apply()
}
/** 獲取時(shí)間設(shè)置 */
private fun getSpfThemeTimer() : String = mSpf.getString(SPF_THEME_TIMER, null)?: "18:00~08:00"
/** 設(shè)置時(shí)間 */
private fun setSpfThemeTimer(timer: String) {
mSpf.edit().putString(SPF_THEME_TIMER, timer).apply()
}
/** 獲取設(shè)置好的ThemeMode */
fun getThemeMode(): ThemeMode = ThemeMode.parseOfInt(getSpfThemeMode())
/** 設(shè)置模式 */
fun setThemeMode(mode: ThemeMode) {
setSpfThemeMode(mode.intValue)
}
/** 獲取設(shè)置好的定時(shí)時(shí)間 */
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()
)
}
/** 設(shè)置定時(shí)時(shí)間 */
fun setThemeTime(time: ThemeTime) {
setSpfThemeTimer(time.toTimerString())
}
/**
* 應(yīng)用存儲(chǔ)的設(shè)置
*/
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é)束時(shí)間和開(kāi)始時(shí)間都在同一天
if (curTime > startTime && curTime < stopTime) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
} else {
// 結(jié)束時(shí)間在開(kāi)始時(shí)間的后一天
if (curTime > startTime || curTime < stopTime) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
}
}
})
}
}
/**
* 主題設(shè)置時(shí)間
*/
data class ThemeTime(
// 開(kāi)始小時(shí)
val beginHour: Int,
// 開(kāi)始分鐘
val beginMinute: Int,
// 結(jié)束小時(shí)
val endHour: Int,
// 結(jié)束分鐘
val endMinute: Int,
// 開(kāi)始時(shí)間
var startTime: String = "00:00",
// 結(jié)束時(shí)間
var stopTime: String = "00:00"
) : Serializable {
init {
startTime = "${upTo2String(beginHour)}:${upTo2String(beginMinute)}"
stopTime = "${upTo2String(endHour)}:${upTo2String(endMinute)}"
}
fun toTimerString() : String = "$startTime~$stopTime"
// 保存成長(zhǎng)度為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)
}
}
還有一個(gè)主題列表
/**
* 主題開(kāi)啟模式
* @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
}
}
}
}
字符串在這里
一直開(kāi)啟
一直關(guān)閉
跟隨系統(tǒng)設(shè)置
定時(shí)開(kāi)啟
使用方法
首先在Aplication的onCreate中啟動(dòng)保存設(shè)置
override fun onCreate() {
super.onCreate()
// 應(yīng)用主題設(shè)置
NightModeUtils.getInstance(this).applySetting()
}
然后在你的Activity(最好有BaseActivity)中的onResume中同樣加入啟動(dòng)設(shè)置
override fun onResume() {
super.onResume()
NightModeUtils.getInstance(this).applySetting()
}
以上就能保證頁(yè)面能順利切換主題了。
設(shè)置主題
NightModeUtils.getInstance(this).setThemeMode(ThemeMode.MODE_TIMER)
設(shè)置定時(shí)
val time = ThemeTime(
endHour = 18,
endMinute = 0,
beginHour = 8,
beginMinute = 0
)
NightModeUtils.getInstance(this).setThemeTime(time)
應(yīng)用設(shè)置
NightModeUtils.getInstance(this).applySetting()
大功告成
照著走就沒(méi)毛病了。
最后
我覺(jué)得有一個(gè)朋友說(shuō)的話(huà)很對(duì):Android學(xué)習(xí),我們要學(xué)習(xí)的東西不僅僅只有表面的 技術(shù),還要深入底層,弄明白下面的 原理,只有這樣,我們才能夠提高自己的競(jìng)爭(zhēng)力,在當(dāng)今這個(gè)競(jìng)爭(zhēng)激烈的世界里立足。
我把自己這段時(shí)間整理的Android最重要最熱門(mén)的學(xué)習(xí)方向資料放在了我的GitHub(點(diǎn)擊此處可查看),里面還有不同方向的自學(xué)編程路線(xiàn)、面試題集合/面經(jīng)、及系列技術(shù)文章等。
歡迎大家一起學(xué)習(xí)和探討。
總結(jié)
以上是生活随笔為你收集整理的android自动切换暗色,超实用!Android 深色模式适配(可定时开启的APP内主题切换管理工具)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Chainer Chemistry |
- 下一篇: android 图片热点区域,Andro