17

I know this question was asked few times. but I cant find the problem in my case. I want to change the theme of the app but my colorPrimary ,colorAccent and etc.. aren't changing.

my MainActivity extends BasicActivity. it looks like this:

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);

}
}

this is my BasicActivity(in this case I made it even simpler to show that the theme is taken from 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);

    }

}

and my 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>

According to the previous questions this code should work but in my case the views that have colorPrimary in their XML still loading the old theme's colors insted of the new one even though i set the theme before calling setContentView(R.layout.activity_main);

Thanks!

Max
  • 319
  • 1
  • 4
  • 18
  • 1
    You have hard-coded the theme in BaseActivity , than getting referring resource id. You need to put setTheme(value_from_resourceId); The BaseActivity always calls setTheme(R.style.c_2ecc71_BC6C2B); than a runtime value – Sreehari Jan 10 '17 at 09:41

7 Answers7

14

If you use Fragments, they will ignore the value you have set in the onCreate(), if you override the getTheme() method, it will be used within fragments as well:

Answered on different question: 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;
}

Use it in your MainActivity or your BasicActivity depending on where you want it to apply. You will NOT need to change it in the onCreate anymore.

Community
  • 1
  • 1
Björn Kechel
  • 7,933
  • 3
  • 54
  • 57
7

You are trying to extend one of the newer themes of Android (above API 21). In addition to all the answers above , you can put your theme in styles.xml(v21).

More info here https://developer.android.com/training/material/compatibility.htmlenter image description here

BMU
  • 429
  • 2
  • 9
2

Not sure if you really want to set it programmatically, but you might try this: How to setTheme to an activity at runtime? It doesn't work call setTheme before onCreate and setContentView

If you're looking to set it for the whole application, it might be easier/cleaner to set it in the AndroidManifest.xml file instead.

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

Also, I'd highly avoid using a style name that has the values in it. The point of using a style is to avoid hard coding the values and allowing them to be configurable and reusable. What if you want to change the colorPrimary, are you also going to change your style name?

Community
  • 1
  • 1
Scott Merritt
  • 1,284
  • 2
  • 13
  • 24
  • I want to be able to change it dinamically in runtime – Max Jan 05 '17 at 21:34
  • Yes, that's what the first link in the answer explains. You should be able to do it like this code: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(android.R.style.Theme_Translucent_NoTitleBar); // Set here setContentView(...) } – Scott Merritt Jan 06 '17 at 14:31
2

To set theme at runtime you can use following line of code :

setTheme(android.R.style.Theme_Name);

and write it before calling setContentView() and super.onCreate() method inside onCreate() method.

Community
  • 1
  • 1
Sharanjeet Kaur
  • 796
  • 13
  • 18
2

If you want to change that kind of stuff during runtime, you must insert all those "setTheme(android.R.style.Theme_Name);" methods inside runonUiThread, like this:

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);

}

}

and call recreate() after!

According to Android -

void recreate () Cause this Activity to be recreated with a new instance. This results in essentially the same flow as when the Activity is created due to a configuration change -- the current instance will go through its lifecycle to onDestroy() and a new instance then created after it.

omriherman
  • 254
  • 1
  • 12
2

Just modify your BasicActivity and MainActivity as shown in below and create appropriate theme. You can use shared preference for checking theme state during app up.

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;
    }
   }
Mable John
  • 4,518
  • 3
  • 22
  • 35
2

You have hard-coded the theme in BaseActivity , rather than getting targetted resource id.

You need to put setTheme(value_from_resourceId);

Currently the BaseActivity always calls irrespective of value that you parsed

setTheme(R.style.c_2ecc71_BC6C2B);

than referring the runtime value

Sreehari
  • 5,621
  • 2
  • 25
  • 59