2

I'm building a material design playground that can switch between the available pre-defined themes that can apply the color, typography and shapes to all the material design components throughout the app.

Right now, the user can choose available themes from the PreferenceScreen:

enter image description here

I got a NEW requirement that should allow the user to enter a value (eg. set color of colorPrimary). From the input, I would like to modify the Theme directly so that it could apply the change in the app.

How can I do this? I'm thinking of giving an option to the user something like below:

enter image description here

Here's a link to my sample material design playground app: https://github.com/ciscosoriano/material-design-dynamic-theming

ciscocode
  • 21
  • 2

1 Answers1

0

Seems like you need something like this android-how-to-change-application-theme-programmatically

link: android-how-to-change-application-theme-programmatically

This should be easy and there are lot of tutorials out there, don't forget to checkout

Basically what you need to do is:

  1. apply statically defined theme(in res/values) as usual before activity is launched.
  2. Now get the user input when activity is launched
  3. Then get the current theme attributes using appropriate api and recolourize the ui controls dynamically in the program.
  4. restart activity with the updated theme.

Some more link: Set theme color dynamically

You should be comfortable handling the activity lifecycle to view the updated theme when set.

mahee96
  • 705
  • 6
  • 15
  • Thanks for sharing this! But I'm doing this in my sample app already. Also, I saw that the color is being set per component. But my goal is to set the color globally in the app. Let's say if I would have 50 buttons, I want to apply the same color to all of them, but not set it one by one per button. – ciscocode Jul 21 '21 at 16:26
  • @ciscocode, if you target the entire theme color say "primaryColor", then the controls which inherit the theme should also reflect the changes, if this is not what is happening, then your controls aren't probably inheriting the parent theme set by the activity. – mahee96 Jul 21 '21 at 17:36
  • @ciscocode or if you mean to say, you want to do this universally, ie the theme changer part of code to be universal in the application, then you can move the theme management code into BaseActivity which is parent to any activity (all activities must extend this BaseActivity) and have it worked upon automatically when any new activity gets created. – mahee96 Jul 21 '21 at 17:39
  • Just a hint: Have the theme chooser fragment/activity store the chosen theme into a preference, then when creating a new activity or navigating into another activity let the BaseActivity which has the theme management code to check this hardened preference and update the current theme if its not already updated when creating the target activity. – mahee96 Jul 21 '21 at 17:42
  • if the control themes inherit the main application theme, then any changes to application theme should be applied to the controls automatically <== This is the key point to entire application theme customization. – mahee96 Jul 21 '21 at 17:43
  • Does this mean I have to setColor manually for each of the components of the Activity/Fragment that I have? – ciscocode Jul 27 '21 at 03:10
  • Is it possible to get control of the Material Design theme through code programmatically? I want to mimic the same behavior as how Material Design can apply the theme to each of the components. – ciscocode Jul 27 '21 at 03:12
  • https://mobicodeblog.wordpress.com/2016/09/03/dynamic-theme-switching-in-android-without-activity-restart/ – mahee96 Jul 28 '21 at 11:44
  • That link tells you how to have an abstract base activity which applies the theme before start of an activity. – mahee96 Jul 28 '21 at 11:46
  • https://stackoverflow.com/questions/27231258/android-how-to-i-apply-a-theme-to-all-the-activities-of-application-after-selec – mahee96 Jul 28 '21 at 11:46
  • if you want to let the user customize the complete theme (Each attribute), then obviously you need to mimic what the theme engine does internally, ie set again the new attributes for current theme and re-display current theme with updated attributes. – mahee96 Jul 28 '21 at 11:49
  • Thanks @mahee96 ! How can I modify the colors.xml file in the resources either through API or through Reflection? – ciscocode Jul 28 '21 at 19:57
  • All the items in XML are static default config which is always present in the application and shipped with it, any customisation related data goes into preferences or databases. What I mean to say is, you don't modify colors.xml instead you get the color attribute which u want using getResources().getcolor() from XML attribs then save the color into persistent storage such as preference or database and get the attribute that was saved last time from preferences at startup in the abstract base activity then set current theme color using it. – mahee96 Jul 29 '21 at 08:28
  • I do understand this is lengthy but is one time investment to setup (helper) DynamicThemeEngine.java class as per your needs and invoke it to setup theme in the base activity. Just get your design first on paper and think how it will fit for re-use....use SOLID principles for the design then you are good to go. – mahee96 Jul 29 '21 at 08:31