I have about 7 activities and somewhere in the 6th I need to insert into the settings a switch for choosing a light or dark theme.

Using this code does not help:

public void theme(View view){ getApplication().setTheme(android.R.style.Theme_Holo); } 

I read that it is necessary to prescribe a separate class, which is called in each activity class before setContentView .

    2 answers 2

    To change the topic "on the fly" you need to do quite tedious manipulations.

    Usually all this happens in the settings.
    Through the setTheme() method, you can set the desired topic in each activation, the changes will take effect after the restart of the activation (return from settings), in which there is a change of topic. The method must be used BEFORE the setContentView() method.

    The current selected theme is best stored in SharedPreferences , writing the value from the settings there, and when starting, activate it from there.

     public void onCreate(Bundle savedInstanceState) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); int theme = sp.getInt("THEME", R.style.AppTheme); setTheme(theme); super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); } 

    where the value of the key "THEME", which will be recorded in the settings, is equal to the ID of the selected theme specified in res / styles.xml , so, for an example with styles below, these will be the values: R.style.AppTheme and R.style.AppThemeLight

    UPD

    For themes based on AppCompat themes are not fully applied, to solve this problem, you must specify the colors ColorPrimary , ColorPrimaryDark and ColorAccent in the styles.xml with the themes that will change in the application:

    styles.xml

     <resources> <style name="AppThemeLight" parent="@style/Theme.AppCompat.Light"> <item name="colorPrimary">@color/primary_light</item> <item name="colorPrimaryDark">@color/primary_dark_light</item> <item name="colorAccent">@color/accent_light</item> </style> <style name="AppTheme" parent="@style/Theme.AppCompat"> <item name="colorPrimary">@color/primary</item> <item name="colorPrimaryDark">@color/primary_dark</item> <item name="colorAccent">@color/accent</item> </style> </resources> 

    We define the colors themselves (you can choose your own ones, which ones you like) in colors.xml :

     <resources> <color name="primary_light">#edeceb</color> <color name="accent_light">#517c50</color> <color name="primary_dark_light">#0d0c0c</color> <color name="primary">#2d2c2a</color> <color name="accent">#a5c0df</color> <color name="primary_dark">#e2e0e0</color> </resources> 

    For themes based on Holo , you also need to specify some parameters so that there are no problems:

    styles.xml

     <resources> <style name="AppThemeLight" parent="android:Theme.Holo.Light"> <item name="android:background">#FFFFFF</item> <item name="android:textColor">#000000</item> <item name="android:actionBarStyle">@style/LightActionBar</item> </style> <style name="AppTheme" parent="android:Theme.Holo"> <item name="android:background">#000000</item> <item name="android:textColor">#FFFFFF</item> <item name="android:actionBarStyle">@style/BlackActionBar</item> </style> <style name="LightActionBar" parent="@android:style/Widget.Holo.Light.ActionBar"> <item name="android:background">#FFFFFF</item> </style> <style name="BlackActionBar" parent="@android:style/Widget.Holo.ActionBar"> <item name="android:background">#000000</item> </style> </resources> 

    PS: Guaranteed application of the theme will occur when the application is restarted (and in general when the activation is restarted, which does not always happen, since they are not necessarily destroyed during the transitions)

    • Activation of recreating is not necessary, it is enough to recreate a fragment [s] of which this activation consists ... Well, it depends, yes ... - Yura Ivanov
    • I tried, themes switches. But all the same there is white text on a white background in a light theme. Could this be due to the use of Appcompat? - Igor
    • I also have the same, I use a change of topics, a change of topic, for example on a black one, the title remains black and so black on black is not very good. And I tried it as you said, so finally an interesting bug comes out - Denis Kotlyarov
    • For example, like this, if you make a change of topic above super.OnCreate two bar status goes out !!! The theme was applied to the second status bar) and the app itself is white) - Denis Kotlyarov
    • yadi.sk/i/HGUX6iDlibKN7 - Denis Kotlyarov

    In general, it worked even without defining primary colors.

    There are three themes in styles:

     style name="AppBaseTheme" parent="Theme.AppCompat"></style> style name="AppTheme" parent="AppBaseTheme"></style> style name="AppTheme.Light" parent = "Theme.AppCompat.Light"></style> 

    in the manifest:

      > android:theme="@style/AppBaseTheme" 

    in each activity (a variable containing the value of the theme is checked):

     public void onCreate(Bundle savedInstanceState) { if (MainActivity.theme.equals("white")) { setTheme(R.style.AppTheme_Light); } else setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); 

    and directly switch (overloads the activity and sets the variable to the desired color for the rest):

     MainActivity.theme="white"; Intent intent2 = getIntent(); finish(); startActivity(intent2); 
    • one
      It is not recommended to use the activation field for storing values ​​outside this activation, as it may be lost at any time. Use SharedPreferences to store the selected theme. - pavlofff
    • You are right, but SharedPreferences for some reason do not work for me, no matter how I dance with a tambourine. It is clear that the chosen theme will not be saved after I restart the application, but I cannot save them to a file yet ( - Igor
    • one
      Create a question with your problem, maybe you can help solve it. The theme is not only not retained when you restart, but can be quite easily lost while the application is running. - pavlofff
    • Well, thanks, I will try! This is a temporary stub until it is fully operational. - Igor