以编程方式更改活动的主题

use*_*299 104 android

在特殊情况下,我需要从我的活动中删除对话框主题,但它似乎不起作用.这是一个例子

第一项活动:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
Run Code Online (Sandbox Code Playgroud)

第二项活动:

public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setTheme(android.R.style.Theme);
    setContentView(R.layout.activity_second);
}
Run Code Online (Sandbox Code Playgroud)

清单摘录:

 <activity android:name="SecondActivity" android:theme="@android:style/Theme.Dialog"></activity>
Run Code Online (Sandbox Code Playgroud)

当我运行它仍然是对话主题.

API10

谢谢.

use*_*299 159

正如文档所说,你必须setTheme在任何视图输出之前调用.似乎super.onCreate()参与view处理.

所以,主题之间切换动态,你只需要调用setTheme之前super.onCreate是这样的:

public void onCreate(Bundle savedInstanceState) {
    setTheme(android.R.style.Theme);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
}
Run Code Online (Sandbox Code Playgroud)

  • 适合我!但片段中的怎么办改变了? (2认同)

Bjö*_*hel 35

user1462299的响应效果很好,但是如果包含片段,它们将使用原始活动主题.要将主题应用于所有片段,您可以覆盖 Context 的getTheme()方法:

@Override
public Resources.Theme getTheme() {
    Resources.Theme theme = super.getTheme();
    if(useAlternativeTheme){
        theme.applyStyle(R.style.AlternativeTheme, true);
    }
    // you could also use a switch if you have many themes that could apply
    return theme;
}
Run Code Online (Sandbox Code Playgroud)

您不再需要在onCreate()方法中调用setTheme().您正在以这种方式覆盖在此上下文中获取当前主题的每个请求.

  • getTheme() 应该在 Activity 中还是在相应的 Fragments 中被重写?我已经在 Activity 中实现了这一点,但 Fragments 仍然使用原始的 Activity 主题。 (2认同)
  • 好点 user1269737 所以你应该确保没有繁重的计算。简单地在一个简单的条件情况下返回一个样式不会影响性能。 (2认同)
  • 在 2021 年,这不是一个好的解决方案。我已经发布了这段代码,看来 `getTheme` 被调用了很多,而 `applyStyle` 是一个相对繁重的操作。在相对低端的设备上,我可能会耗尽应用程序的内存,并且 OOM 会进出片段几次。因此,要么您需要确保仅调用一次“applyStyle”,要么只使用接受的答案(/sf/answers/810358251/),这些天**确实在片段上设置了主题**当然也只被调用一次。 (2认同)

don*_*don 11

我知道我迟到了,但我想在这里发表一个解决方案:
检查完整的源代码在这里.
这是我在使用首选项更改主题时使用的代码.

SharedPreferences pref = PreferenceManager
        .getDefaultSharedPreferences(this);
String themeName = pref.getString("prefSyncFrequency3", "Theme1");
if (themeName.equals("Africa")) {
    setTheme(R.style.AppTheme);



} else if (themeName.equals("Colorful Beach")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
    setTheme(R.style.beach);


} else if (themeName.equals("Abstract")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();

    setTheme(R.style.abstract2);

} else if (themeName.equals("Default")) {

    setTheme(R.style.defaulttheme);

}
Run Code Online (Sandbox Code Playgroud)

请注意,您必须在setcontentview之前放置代码.

快乐的编码!


Tam*_*afi 5

这个对我来说效果很好:

theme.applyStyle(R.style.AppTheme, true)

用法:

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //The call goes right after super.onCreate() and before setContentView()
    theme.applyStyle(R.style.AppTheme, true)
    setContentView(layoutId)
    onViewCreated(savedInstanceState)
}
Run Code Online (Sandbox Code Playgroud)

或使用setTheme(R.style.AppTheme_Light)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //The call goes right after super.onCreate() and before setContentView()
    setTheme(R.style.AppTheme_Light)
    setContentView(R.layout.activity_main)
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我已经使用这段代码来实现黑暗模式...它对我来说工作得很好...您可以在开关中使用它...监听器...

//setting up Night Mode...
 AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
//Store current mode in a sharedprefernce to retrieve on restarting app
            editor.putBoolean("NightMode", true);
            editor.apply();
//restart all the activities to apply changed mode...
            TaskStackBuilder.create(getActivity())
                    .addNextIntent(new Intent(getActivity(), MainActivity.class))
                    .addNextIntent(getActivity().getIntent())
                    .startActivities();

Run Code Online (Sandbox Code Playgroud)