setTheme不更改主题颜色

时间:2016-12-21 13:35:25

标签: android themes

我知道这个问题几次被问过。但我无法在我的案例中找到问题。 我想改变应用程序的主题,但我的colorPrimary,colorAccent等等都没有改变。

我的MainActivity扩展了BasicActivity。它看起来像这样:

public class MainActivity extends BasicActivity {
    public static String MY_PREFS = "MY_PREFS";
    private SharedPreferences mySharedPreferences;
    int prefMode = Activity.MODE_PRIVATE;

    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private ViewPagerAdapter adapter;
    private TextView tabOne, tabTwo, tabThree;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

}
}

这是我的BasicActivity(在这种情况下,我更简单地表明主题来自R.style):

public class BasicActivity extends AppCompatActivity {

    public static String MY_PREFS = "MY_PREFS";
    int prefMode = Activity.MODE_PRIVATE;



    protected void onCreate(Bundle savedInstanceState) {


        JsonParser parser = new JsonParser(getApplicationContext());

        int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());
        setTheme(R.style.c_2ecc71_BC6C2B);


        if (android.os.Build.VERSION.SDK_INT >= 19) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        }

        super.onCreate(savedInstanceState);

    }

}

和我的XML:

<style name="c_2ecc71_BC6C2B" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">#2ecc71</item>
    <item name="colorPrimaryDark">#1ebc61</item>
    <item name="colorAccent">#BC6C2B</item>
</style>

根据前面的问题,这段代码应该可以工作,但在我的情况下,即使我在调用setContentView(R.layout.activity_main);

谢谢!

8 个答案:

答案 0 :(得分:5)

如果使用Fragments,它们将忽略你在onCreate()中设置的值,如果你覆盖了getTheme()方法,它也会在片段中使用:

回答了不同的问题:Change Activity's theme programmatically

@Override
public Resources.Theme getTheme() {
    Resources.Theme theme = super.getTheme();
    theme.applyStyle(R.style.c_2ecc71_BC6C2B, true);
    return theme;
}

在MainActivity或BasicActivity中使用它,具体取决于您希望它应用于何处。你不需要在onCreate中更改它了。

答案 1 :(得分:4)

您正在尝试扩展Android的一个较新主题(API 21以上)。除了上面的所有答案,您还可以将主题放在styles.xml(v21)中。

此处有更多信息https://developer.android.com/training/material/compatibility.html enter image description here

答案 2 :(得分:1)

不确定是否确实要以编程方式设置它,但您可以尝试这样做:How to setTheme to an activity at runtime? It doesn't work call setTheme before onCreate and setContentView

如果您正在寻找为整个应用程序设置它,那么在AndroidManifest.xml文件中设置它可能更容易/更清晰。

<application android:theme="@style/CustomTheme">

另外,我高度避免使用包含值的样式名称。使用样式的目的是避免对值进行硬编码并允许它们可配置和可重用。如果你想改变colorPrimary怎么办?你还要改变你的样式名称吗?

答案 3 :(得分:1)

在清单文件中,确保活动的主题正确....

答案 4 :(得分:1)

如果你想在运行时更改那种东西,你必须插入所有那些“setTheme(android.R.style.Theme_Name);” runonUiThread中的方法,如下所示:

public class BasicActivity extends AppCompatActivity {

public static String MY_PREFS = "MY_PREFS";
int prefMode = Activity.MODE_PRIVATE;



protected void onCreate(Bundle savedInstanceState) {


    JsonParser parser = new JsonParser(getApplicationContext());

    int resourceId = this.getResources().getIdentifier(parser.getThemeID(), "style", this.getPackageName());

    runOnUiThread(new Runnable() {

                    @Override
                    public void run() {

                     setTheme(R.style.c_2ecc71_BC6C2B);
                    }
                });

    recreate();
    if (android.os.Build.VERSION.SDK_INT >= 19) {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    }

    super.onCreate(savedInstanceState);

}

}

并在!

之后调用recreate()

根据Android -

  

void recreate()   导致使用新实例重新创建此活动。这导致与由于配置更改而创建Activity时基本相同的流 - 当前实例将经历其生命周期到onDestroy(),然后在其之后创建新实例。

答案 5 :(得分:1)

只需修改您的BasicActivity和MainActivity,如下所示,并创建适当的主题。您可以在应用期间使用共享首选项来检查主题状态。

BasicActivity .java

public abstract class BasicActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    try {
        if (getLayoutID() != 0) {
            setContentView(getLayoutID());
        }
    } catch (Exception ex) { /* ... */ }

    final boolean THEME_DARK = true;// read appropriate value from SP or any other storage

    Toolbar toolbar;
    if ((toolbar = getToolbar()) != null) {
        if (THEME_DARK/*  check theme type here*/) {
            toolbar.setPopupTheme(R.style.c_2ecc71_BC6C2B);
        }
        try {
            setSupportActionBar(toolbar);
        } catch (NoClassDefFoundError e) {
            // Toast
            finish();
        }
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.setStatusBarColor(getResources().getColor(R.color.colorPrimary));
    }
}

public abstract Toolbar getToolbar();

public abstract int getLayoutID();

}     

MainActivity.java

    public class MainActivity extends BasicActivity {

    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public Toolbar getToolbar() {
        return toolbar == null ? toolbar = (Toolbar) findViewById(R.id.toolbar) : toolbar;
    }

    @Override
    public int getLayoutID() {
        return R.layout.activity_main;
    }
   }

答案 6 :(得分:1)

您已在BaseActivity中对主题进行了硬编码,而不是获取目标资源ID。

您需要放置setTheme(value_from_resourceId);

目前,无论您解析的值是什么,BaseActivity总是会调用

setTheme(R.style.c_2ecc71_BC6C2B);

而不是引用运行时值

答案 7 :(得分:0)

要在运行时设置主题,您可以使用以下代码行:

setTheme(android.R.style.Theme_Name);

在onCreate()方法中调用setContentView()和super.onCreate()方法之前编写它。