我无法在Android应用中实现主题选择。
之前曾问过这个问题,但解决方法 - 在setContentView之前调用application.setTheme(theme_id) - 对我来说不起作用。
在styles.xml中定义了2个主题:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<!-- second theme, hard coded colors for testing -->
<style name="DarkTheme" parent="Theme.AppCompat.DayNight">
<item name="colorPrimary">#ff0000</item>
<item name="colorPrimaryDark">#00ff00</item>
<item name="colorAccent">#0000ff</item>
</style>
这两个主题都可以在AndroidManifest.xml中使用:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
或
<application
...
android:theme="@style/DarkTheme"
>
...
</application>
结果如预期,风格不同。
但是主题选择应该由用户完成,所以我在清单中使用android:theme="@style/AppTheme"
测试了基本功能并对其进行了硬编码:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// yes, the line appears in the log:
Log.d("MYAPP", "calling application.setTheme(R.style.DarkTheme)")
application.setTheme(R.style.DarkTheme)
setContentView(R.layout.activity_main)
}
}
结果:仍在使用AndroidManifest.xml中定义的主题,setTheme调用无效。
没有编译警告,没有运行时消息,没有可疑的日志条目。
使用Kotlin,但这不应该是问题的原因。
答案 0 :(得分:0)
最后我设法让它发挥作用。
要明确:我先发布的代码:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
application.setTheme(R.style.DarkTheme)
setContentView(R.layout.activity_main)
}
}
根据SO上类似问题的许多答案,应该工作。
但事实并非如此。
还有:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
application.setTheme(R.style.DarkTheme)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
或函数调用序列中的其他排列不能解决问题。
不是真正的解决方案,但问题的解决方法是BjörnKechel的答案,在此处找到:Change Activity's theme programmatically
覆盖Activity中的getTheme方法,而不是调用无功能的setTheme方法:
class MainActivity : AppCompatActivity() {
protected var selectedTheme : String = ""
lateinit protected var sharedPreferences : SharedPreferences
var initialized = false
fun init() {
if (!initialized) {
initialized = true
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
}
if ("" == selectedTheme) {
selectedTheme = sharedPreferences.getString("selected_theme", "AppTheme")
}
}
override fun getTheme(): Resources.Theme {
init()
val theme = super.getTheme()
when(selectedTheme) {
"DarkTheme" -> {
theme.applyStyle(R.style.DarkTheme, true)
}
"AppTheme" -> {
theme.applyStyle(R.style.AppTheme, true)
}
}
return theme
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
settings.setOnClickListener {
openSettings()
}
}
fun openSettings() {
val intent = Intent(baseContext, SettingsActivity::class.java)
startActivity(intent)
}
}