无法在我的应用程序中设置代码中的主题

时间:2018-04-18 12:51:46

标签: android android-theme

我无法在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,但这不应该是问题的原因。

1 个答案:

答案 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)
  }
}