以下是 SettingsActivity.kt 文件中每一行代码的深度解析:
🧩 1. 类定义与生命周期
kotlin
class SettingsActivity : AppCompatActivity() {
- 说明 : 定义 SettingsActivity 类,继承自
AppCompatActivity
,以支持 Material Design 风格和向后兼容性。
kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- 说明 : 重写 onCreate() 方法,这是 Activity 的入口点。
super.onCreate(savedInstanceState)
调用父类方法,确保基础初始化逻辑执行。
🌗 2. 主题适配与状态栏颜色设置
kotlin
// Themes
val themes = Themes(this)
themes.applyDayNightOverride()
setTheme(themes.getTheme())
- 说明 :
- 创建 Themes 实例,传入当前上下文
this
。 - applyDayNightOverride() 强制应用当前主题(如深色或浅色模式)。
setTheme(themes.getTheme())
设置当前 Activity 的主题样式。
- 创建 Themes 实例,传入当前上下文
kotlin
setContentView(R.layout.settings_activity)
- 说明 : 加载 settings_activity.xml 布局文件作为主界面。
kotlin
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.replace(R.id.settings, SettingsFragment())
.commit()
}
- 说明 :
- 检查是否为首次创建(无保存实例状态)。
- 使用
supportFragmentManager
开始一个 Fragment 事务。 - 替换
R.id.settings
容器视图的内容为SettingsFragment
。 commit()
提交事务以完成 Fragment 的加载。
kotlin
supportActionBar?.setDisplayHomeAsUpEnabled(true)
- 说明: 显示返回按钮(HomeAsUp),方便用户返回上一级。
kotlin
// Change the status bar color
if (MyPreferences(this).theme == 1) { // Amoled theme
window.statusBarColor = ContextCompat.getColor(this, R.color.amoled_background_color)
} else {
window.statusBarColor = ContextCompat.getColor(this, R.color.background_color)
}
- 说明 :
- 使用
MyPreferences
获取用户选择的主题 ID。 - 如果是 Amoled 主题 (
theme == 1
),则使用黑色背景作为状态栏颜色。 - 否则使用默认背景色。
ContextCompat.getColor()
确保在不同 API 版本上都能正确获取颜色资源。
- 使用
kotlin
// back button
findViewById<ImageView>(R.id.settings_back_button).setOnClickListener {
finish()
}
- 说明 :
- 找到
R.id.settings_back_button
对应的 ImageView。 - 设置点击监听器,当用户点击时调用
finish()
关闭当前 Activity。
- 找到
⚙️ 3. 设置项实现:SettingsFragment
✅ 初始化设置项
kotlin
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
- 说明 :
- 从
res/xml/root_preferences.xml
加载预设的设置项。 - 这些设置项通常包含主题、语言、数字系统等选项。
- 从
🌍 语言设置
kotlin
val appLanguagePreference = findPreference<Preference>("darkempire78.opencalculator.APP_LANGUAGE")
- 说明 : 查找键为
"darkempire78.opencalculator.APP_LANGUAGE"
的 Preference。
kotlin
// remove the app language button if you are using an Android version lower than v33 (Android 13)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
appLanguagePreference?.isVisible = false
} else {
// Display the current selected language
appLanguagePreference?.summary = Locale.getDefault().displayLanguage
}
- 说明 :
- 如果设备运行的是低于 Android 13(API 33)的版本,则隐藏语言设置项。
- 否则显示当前系统的语言名称作为摘要。
kotlin
// Select app language button
appLanguagePreference?.setOnPreferenceClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
launchChangeAppLanguageIntent()
}
true
}
- 说明 :
- 设置点击监听器,在 Android 13 及以上版本中调用
launchChangeAppLanguageIntent()
打开系统语言设置。
- 设置点击监听器,在 Android 13 及以上版本中调用
🎨 主题设置
kotlin
// Theme button
val appThemePreference = findPreference<Preference>("darkempire78.opencalculator.APP_THEME_SELECTOR")
- 说明 : 查找键为
"darkempire78.opencalculator.APP_THEME_SELECTOR"
的 Preference。
kotlin
appThemePreference?.summary = Themes(this.requireContext()).getThemeNameFromId(
MyPreferences(this.requireContext()).theme)
- 说明: 获取当前主题名称并设置为摘要文本。
kotlin
appThemePreference?.setOnPreferenceClickListener {
Themes.openDialogThemeSelector(this.requireContext())
true
}
- 说明: 设置点击监听器,点击后弹出主题选择对话框。
🔢 数字系统设置
kotlin
// Numbering System button
val appNumberingSystemPreference =
findPreference<Preference>("darkempire78.opencalculator.NUMBERING_SYSTEM")
- 说明 : 查找键为
"darkempire78.opencalculator.NUMBERING_SYSTEM"
的 Preference。
kotlin
appNumberingSystemPreference?.summary =
NumberingSystem.getDescription(MyPreferences(this.requireContext()).numberingSystem)
- 说明: 获取当前数字系统描述并设置为摘要文本。
kotlin
appNumberingSystemPreference?.setOnPreferenceClickListener {
openDialogNumberingSystemSelector(this.requireContext())
true
}
- 说明: 设置点击监听器,点击后弹出数字系统选择对话框。
💬 4. 对话框实现
✅ 数字系统选择对话框
kotlin
private fun openDialogNumberingSystemSelector(context: Context) {
val preferences = MyPreferences(context)
val builder = MaterialAlertDialogBuilder(context)
builder.background = ContextCompat.getDrawable(context, R.drawable.rounded)
- 说明 :
- 创建
MaterialAlertDialogBuilder
实例,并设置自定义背景。
- 创建
kotlin
val numberingSystem = hashMapOf(
0 to NumberingSystem.INTERNATIONAL.description,
1 to NumberingSystem.INDIAN.description
)
- 说明: 创建数字系统映射表,包含国际格式和印度格式。
kotlin
val checkedItem = preferences.numberingSystem
builder.setSingleChoiceItems(
numberingSystem.values.toTypedArray(),
checkedItem
) { dialog, which ->
when (which) {
0 -> {
preferences.numberingSystem = 0
}
1 -> {
preferences.numberingSystem = 1
}
}
dialog.dismiss()
reloadActivity(requireContext())
}
- 说明 :
- 显示单选对话框,允许用户选择数字系统。
- 用户选择后更新偏好设置,并调用
reloadActivity()
重启 Activity。
kotlin
val dialog = builder.create()
dialog.show()
}
- 说明: 创建并显示对话框。
🔁 重启 Activity
kotlin
private fun reloadActivity(context: Context) {
(context as Activity).finish()
ContextCompat.startActivity(context, context.intent, null)
}
- 说明 :
- 结束当前 Activity。
- 重新启动 Activity 以应用新的设置。
🌐 系统语言设置跳转
kotlin
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun launchChangeAppLanguageIntent() {
try {
Intent(Settings.ACTION_APP_LOCALE_SETTINGS).apply {
data = Uri.fromParts("package", requireContext().packageName, null)
startActivity(this)
}
} catch (e: Exception) {
try {
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", requireContext().packageName, null)
startActivity(this)
}
} catch (e: Exception) {
println(e)
}
}
}
- 说明 :
- 构造一个 Intent,打开系统语言设置界面。
- 如果失败,则尝试打开应用详情页。
✅ 总结
该 SettingsActivity.kt 文件实现了 OpenCalc 应用的设置功能,包括:
- 多主题支持(深色、浅色、Amoled)
- 语言设置(仅限 Android 13+)
- 数字系统选择(国际格式和印度格式)
- UI 刷新机制(修改设置后自动重启 Activity)