Change Custom Android Theme Dynamically - java

I have a few customer theme's in my style.xml file. I want to change the theme upon clicking a button in an alertDialog.
When I try to change the theme, I get an error that the class can't be inflated. I verified that the minimum API is at least 21 which from other posts has to be done.
Here is my code:
style.xml
<resources>
<!-- Base application theme. -->
<style name="Theme.easter" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/easter_color_1</item>
<item name="color_2">#color/easter_color_2</item>
<item name="color_3">#color/easter_color_3</item>
<item name="color_4">#color/easter_color_4</item>
<item name="color_5">#color/easter_color_5</item>
</style>
<style name="soft" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/soft_color_1</item>
<item name="color_2">#color/soft_color_2</item>
<item name="color_3">#color/soft_color_3</item>
<item name="color_4">#color/soft_color_4</item>
<item name="color_5">#color/soft_color_5</item>
</style>
<style name="Theme.girl" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/girl_color_1</item>
<item name="color_2">#color/girl_color_2</item>
<item name="color_3">#color/girl_color_3</item>
<item name="color_4">#color/girl_color_4</item>
<item name="color_5">#color/girl_color_5</item>
</style>
<style name="Theme.summer" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/summer_color_1</item>
<item name="color_2">#color/summer_color_2</item>
<item name="color_3">#color/summer_color_3</item>
<item name="color_4">#color/summer_color_4</item>
<item name="color_5">#color/summer_color_5</item>
</style>
<style name="Theme.warm" parent="Theme.AppCompat.Light.NoActionBar">
<item name="color_1">#color/warm_color_1</item>
<item name="color_2">#color/warm_color_2</item>
<item name="color_3">#color/warm_color_3</item>
<item name="color_4">#color/warm_color_4</item>
<item name="color_5">#color/warm_color_5</item>
</style>
</resources>
I am trying to dynamically change the theme using the following code:
#Override public void onClick(DialogInterface dialog, int item) {
switch (item) {
case 0:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.EASTER);
break;
case 1:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.SOFT);
break;
case 2:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.GIRL);
break;
case 3:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.SUMMER);
break;
case 4:
themeUtils.changeToTheme(AdminSettings.this, themeUtils.WARM);
break;
}
}
themeUtils.class
package sourceCode;
import android.app.Activity;
import android.content.Intent;
import com.projects.fbgrecojr.vamoose.R;
/**
* Created by fbgrecojr on 8/26/15.
*/
public class themeUtils {
private static int cTheme;
public final static int EASTER = 0;
public final static int SOFT = 1;
public final static int GIRL = 2;
public final static int SUMMER = 3;
public final static int WARM = 4;
public static void changeToTheme(Activity activity, int theme) {
cTheme = theme;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
public static void onActivityCreateSetTheme(Activity activity) {
switch (cTheme) {
default:
case EASTER:
activity.setTheme(R.style.Theme_easter);
break;
case SOFT:
activity.setTheme(R.style.soft);
break;
case GIRL:
activity.setTheme(R.style.Theme_girl);
break;
case SUMMER:
activity.setTheme(R.style.Theme_summer);
break;
case WARM:
activity.setTheme(R.style.Theme_warm);
break;
}
}
}
finally, in my onCreate() method in the activity that I want to change the theme I have this code:
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
themeUtils.onActivityCreateSetTheme(this);
setContentView(R.layout.activity_admin_settings);
....
}
How can I fix this??

Related

How can I get dark mode to work on my app?

I have set up a ListPreference with different values for the user's dark mode preference. Right now, I just want the app to work with the new dark mode implementation introduced in Android Q. If I set the system dark mode, the app changes because I have enabled isforcedarkallowed in styles.xml.
SettingsFragment:
public static class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
PreferenceScreen screen = getPreferenceScreen();
final ListPreference listPreference = (ListPreference) findPreference("theme");
Preference preference = (Preference) findPreference("notq");
int api = Integer.valueOf(android.os.Build.VERSION.SDK_INT);
if (api > 28) {
screen.removePreference(preference);
}
if (api < 29) {
screen.removePreference(listPreference);
}
listPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
listPreference.setValue(newValue.toString());
theme = String.valueOf(listPreference.getEntry());
Log.d("debug", theme);
if (theme.equals("Light")) {
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO);
}
if (theme.equals("Dark")) {
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES);
}
if (theme.equals("System default")) {
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM);
}
return true;
}
});
}
}
Arrays.xml (values for dark mode preference)
<resources xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Reply Preference -->
<string-array name="theme_entries">
<item>Light</item>
<item>Dark</item>
<item>System default</item>
</string-array>
<string-array name="theme_values">
<item>light</item>
<item>dark</item>
<item>default1</item>
</string-array>
</resources>
My listpreference:
<ListPreference
android:id="#+id/list"
app:entries="#array/theme_entries"
app:entryValues="#array/theme_values"
app:key="theme"
app:title="#string/theme_title"
app:useSimpleSummaryProvider="true" />
And the app theme I'm using (styles.xml):
<style name="AppTheme2" parent="Theme.AppCompat.DayNight.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:forceDarkAllowed" tools:targetApi="q">true</item>
<item name="android:isLightTheme" tools:targetApi="q">true</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#FFFFFF</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
Any suggestions?
In your styles.xml you should not take Theme.AppCompat.DayNight.DarkActionBar as a parent while you enabled forceDarkAllowed. Change that to Theme.AppCompat or Theme.MaterialComponents. You cannot inherit from a daynight theme while forceDarkAllowed is set to true. You can read about that here https://developer.android.com/guide/topics/ui/look-and-feel/darktheme section forcedark.
String theme = String.valueOf(listPreference.getEntry());
Should work fine, you just didn't declare theme as a string
:)

Hide system navigation bar when show DialogFragment

My app is in sticky immersive mode that the system navigation bar (I call it SNB) is hidden in running time of my app. It works well but exists one problem, it is each time I show a DialogFragment, the SNB will be appear. How can I hide it.
I have written a few line of code in my acivity class to make my app become fullscreen and sticky immersive mode.
MyActivity.java
#Override
protected void onResume() {
super.onResume();
hideSystemUI();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
hideSystemUI();
}
public void hideSystemUI() {
// Enables regular immersive sticky mode.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
);
}
MyDialog.java
public class MyDialog extends DialogFragment{
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
AlertDialog alertD = builder.create();
alertD.setView(view);
return alertD;
}
public void show() {
Activity activity = getActivity();
show(activity.getSupportFragmentManager(), "dialog");
}
#Override
public void onResume() {
super.onResume();
ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
getDialog().getWindow().setAttributes((WindowManager.LayoutParams) params);
}
}
I followed the answer to show dialog without show SNB: https://stackoverflow.com/a/33589793/10467639 but it does not work as desired
MyDialog dialog = new MyDialog();
// Set the dialog to not focusable.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
dialog.show();
// Set the dialog to focusable again.
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
style.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/themeColor</item>
<item name="colorPrimaryDark">#color/themeColor</item>
<item name="colorAccent">#color/themeColor</item>
<item name="colorControlNormal">#color/black</item>
<item name="colorControlActivated">#color/black</item>
<item name="colorControlHighlight">#color/white</item>
</style>
<style name="BoldGrayHeaderTextView">
<item name="android:textSize">12dp</item>
<item name="android:fontFamily">#font/nunitosans_bold</item>
<item name="android:textColor">#color/darkColor</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- Splash Screen theme. -->
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">#drawable/splash_background</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<!-- For CarPinItem on Map -->
<style name="carPinItemUnSelected">
<item name="android:textSize">12dp</item>
<item name="android:fontFamily">#font/nunitosans_regular</item>
<item name="android:textColor">#color/generalTextColor</item>
</style>
<style name="carPinItemSelected">
<item name="android:textSize">12dp</item>
<item name="android:fontFamily">#font/nunitosans_regular</item>
<item name="android:textColor">#color/white</item>
</style>
<!-- Style for drawer navigation item -->
<style name="NavigationDrawerStyle">
<item name="android:textSize">15dp</item><!-- text size in menu-->
<item name="android:listPreferredItemHeightSmall">40dp</item><!-- item size in menu-->
<item name="listPreferredItemHeightSmall">40dp</item><!-- item size in menu-->
</style>
<!--Style for textInputEditText -->
<style name="TextInputLayoutStyle">
<item name="android:fontFamily">#font/nunitosans_regular</item>
<item name="android:textSize">13dp</item>
<item name="android:textColor">#color/white</item>
</style>
<!--Style for profile bottom menu -->
<style name="BottomTextLayoutStyle">
<item name="android:fontFamily">#font/nunitosans_regular</item>
<item name="android:textColor">#color/black</item>
</style>
<style name="MyDatePickerStyle" parent="#android:style/Widget.Material.Light.DatePicker">
<item name="android:textColorPrimaryInverse">#color/black</item>
<item name="android:colorControlActivated">#color/successColor</item>
</style>
<style name="Theme.App.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorControlNormal">#color/white</item>
<item name="colorControlActivated">#color/white</item>
<item name="colorControlHighlight">#color/white</item>
</style>
<!--BottomNavivagionView textsize-->
<style name="Widget.BottomNavigationView"
parent="Widget.Design.BottomNavigationView">
<item name="android:fontFamily">#font/nunitosans_regular</item>
</style>
<style name="NoActionBarTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="windowNoTitle">true</item>
</style>
</resources>
How can I solve this problem? Thank in advanced!
Followed this answer https://stackoverflow.com/a/23207365/8531215 ,I have tested and it works fine! modify onCreateDialog() method a little bit
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
AlertDialog alertD = builder.create();
alertD.setView(view);
Dialog dialog = alertD.create();
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
//Show the dialog!
dialog.show();
//Set the dialog to immersive sticky mode
dialog.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
//Clear the not focusable flag from the window
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
return alertD;
}
According to the docs here:
Implement onWindowFocusChanged(). If you gain window focus, you may want to re-hide the system bars. If you lose window focus, for example due to a dialog or pop up menu showing above your app, you'll probably want to cancel any pending "hide" operations you previously scheduled with Handler.postDelayed() or something similar.
So What I suggest you do is, change your code in MyActivity.java from:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
hideSystemUI();
}
to:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if (!hasFocus){
//we lost focus due to DialogFragment
hideSystemUI();
}
}

Theme of app doesn't change dynamically

I am trying to change the theme or color of the app when the user selects an option from an AlertDialog. I made the same technique for changing the size of font, and it's works fine. I don't what is the mistake I made for changing the color.
strings.xml:
<resources>
<string-array name="font_sizes">
<item>14</item>
<item>16</item>
<item>18</item>
<item>20</item>
<item>22</item>
</string-array>
<string-array name="app_colors">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</string-array>
</resources>
styles.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#color/colorPrimaryDark</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="BlackTheme">
<item name="colorPrimary">#FF000000</item>
<item name="colorPrimaryDark">#FF000000</item>
<item name="colorAccent">#FF000000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF000000</item>
</style>
<style name="BlueTheme">
<item name="colorPrimary">#FF0000FF</item>
<item name="colorPrimaryDark">#FF0000FF</item>
<item name="colorAccent">#FF0000FF</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF0000FF</item>
</style>
<style name="GreenTheme">
<item name="colorPrimary">#008000</item>
<item name="colorPrimaryDark">#008000</item>
<item name="colorAccent">#008000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#008000</item>
</style>
<style name="MagentaTheme">
<item name="colorPrimary">#D500F9</item>
<item name="colorPrimaryDark">#D500F9</item>
<item name="colorAccent">#D500F9</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#D500F9</item>
</style>
</resources>
PreferencesActivity.java:
package sa.edu.qu.coc.cocapps.prefs;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.LinearLayout;
import sa.edu.qu.coc.cocapps.R;
public class PreferencesActivity extends AppCompatActivity implements View.OnClickListener {
private Toolbar toolbar = null;
public static final String PREFS_KEY = "preferences";
private static int item = 0, color = 0;
private LinearLayout fontSize;
private LinearLayout appColor;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preferences);
prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
initViews();
setSupportActionBar(toolbar);
fontSize.setOnClickListener(this);
appColor.setOnClickListener(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void initViews() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
fontSize = (LinearLayout) findViewById(R.id.fontSize);
appColor = (LinearLayout) findViewById(R.id.appColor);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.fontSize:
AlertDialog.Builder changeFontSizeDialog = new AlertDialog.Builder(this)
.setTitle("Select Size")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.font_sizes, item, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
editor = prefs.edit();
editor.putInt("fontSize", i);
editor.commit();
item = i;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// DO not do anything.
}
});
changeFontSizeDialog.show();
break;
case R.id.appColor:
AlertDialog.Builder changeAppColorDialog = new AlertDialog.Builder(this)
.setTitle("Select color")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.app_colors, color, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
editor = prefs.edit();
editor.putInt("appColor", which);
editor.commit();
color = which;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// DO not do anything.
}
});
changeAppColorDialog.show();
break;
}
}
#Override
protected void onStart() {
super.onStart();
switch(prefs.getInt("appColor", 0))
{
case 0:
this.setTheme(R.style.AppTheme);
return;
case 1:
this.setTheme(R.style.BlackTheme);
return;
case 2:
this.setTheme(R.style.BlueTheme);
return;
case 3:
this.setTheme(R.style.GreenTheme);
return;
case 4:
this.setTheme(R.style.MagentaTheme);
return;
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
Because themes don't change like that. A theme has to be set before inflating the views. Afterwards, the views will not be refreshed to a new theme. However if you were to create a new View it would pick up the new theme.
Create a base Activity for your app and override onCreate to set the theme. Derive all your other activities from this base Activity.
You can also check this particular tutorial (if you are doing activity theme):
http://mrbool.com/how-to-change-the-layout-theme-of-an-android-application/25837
I solved it. The following code is the whole solution.
strings.xml:
<resources>
<string-array name="font_sizes">
<item>14</item>
<item>16</item>
<item>18</item>
<item>20</item>
<item>22</item>
</string-array>
<string-array name="app_colors">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>
</resources>
styles.xml: (Also, do not forget to add the same custom styles to styles.xml (v21)):
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#color/colorPrimaryDark</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<style name="BlackTheme">
<item name="colorPrimary">#FF000000</item>
<item name="colorPrimaryDark">#FF000000</item>
<item name="colorAccent">#FF000000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF000000</item>
</style>
<style name="BlueTheme">
<item name="colorPrimary">#FF0000FF</item>
<item name="colorPrimaryDark">#FF0000FF</item>
<item name="colorAccent">#FF0000FF</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#FF0000FF</item>
</style>
<style name="GreenTheme">
<item name="colorPrimary">#008000</item>
<item name="colorPrimaryDark">#008000</item>
<item name="colorAccent">#008000</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#008000</item>
</style>
<style name="MagentaTheme">
<item name="colorPrimary">#D500F9</item>
<item name="colorPrimaryDark">#D500F9</item>
<item name="colorAccent">#D500F9</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">#D500F9</item>
</style>
</resources>
PreferencesActivity.java:
package sa.edu.qu.coc.cocapps.prefs;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.LinearLayout;
import sa.edu.qu.coc.cocapps.R;
public class PreferencesActivity extends AppCompatActivity implements View.OnClickListener {
private Toolbar toolbar = null;
private LinearLayout fontSize, appColor;
public static final String PREFS_KEY = "preferences";
private static int item = 0, color = 0;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private Activity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = this;
prefs = getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
switch(prefs.getInt("appColor", 0)) {
case 0:
activity.setTheme(R.style.AppTheme);
break;
case 1:
activity.setTheme(R.style.BlackTheme);
break;
case 2:
activity.setTheme(R.style.BlueTheme);
break;
case 3:
activity.setTheme(R.style.GreenTheme);
break;
case 4:
activity.setTheme(R.style.MagentaTheme);
break;
}
setContentView(R.layout.activity_preferences);
initViews();
setSupportActionBar(toolbar);
fontSize.setOnClickListener(this);
appColor.setOnClickListener(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void initViews() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
fontSize = (LinearLayout) findViewById(R.id.fontSize);
appColor = (LinearLayout) findViewById(R.id.appColor);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.fontSize:
AlertDialog.Builder changeFontSizeDialog = new AlertDialog.Builder(this)
.setTitle("Select Size")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.font_sizes, item, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
editor = prefs.edit();
editor.putInt("fontSize", i);
editor.commit();
item = i;
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// DO not do anything.
}
});
changeFontSizeDialog.show();
break;
case R.id.appColor:
AlertDialog.Builder changeAppColorDialog = new AlertDialog.Builder(this)
.setTitle("Select Color")
.setIcon(android.R.drawable.sym_action_chat)
.setSingleChoiceItems(R.array.app_colors, color, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
editor = prefs.edit();
editor.putInt("appColor", i);
editor.commit();
color = i;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// DO not do anything.
}
});
changeAppColorDialog.show();
break;
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}

Runtime Change Android material theme

I have one setting screen for change app themes at runtime. I know how to create material design theme. I have create one in my style.xml file
Here is code of my style.xml:
<style name="AppTheme" parent="AppTheme.Base"/>
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/primaryBackground</item>
<item name="colorPrimaryDark">#color/primaryBackground</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:colorControlNormal">#color/primaryBackground</item>
<item name="android:colorControlActivated">#color/primaryBackground</item>
<item name="android:colorControlHighlight">#color/primaryBackground</item>
<item name="android:textColorPrimary">#color/primaryBackground</item>
<item name="android:textColorSecondary">#color/primaryBackground</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
<item name="android:textCursorDrawable">#drawable/cursor_indicator</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
Now I want to change runtime app theme from green to purple or yellow. Anything can any one tell me how can I create a color picker from theme selection and how can I create multiple themes in my style.xml for change it to runtime.
Have you seen this demo?
MultipleThemeMaterialDesign
See this class:
public class Preferences {
private static final BoolToStringPref[] PREF_MIGRATION = new BoolToStringPref[]{
new BoolToStringPref(R.string.pref_dark_theme, false,
R.string.pref_theme, R.string.pref_theme_value_red),
};
public static void sync(PreferenceManager preferenceManager) {
Map<String, ?> map = preferenceManager.getSharedPreferences().getAll();
for (String key : map.keySet()) {
sync(preferenceManager, key);
}
}
public static void sync(PreferenceManager preferenceManager, String key) {
Preference pref = preferenceManager.findPreference(key);
if (pref instanceof ListPreference) {
ListPreference listPref = (ListPreference) pref;
pref.setSummary(listPref.getEntry());
}
}
/**
* Migrate from boolean preferences to string preferences. Should be called only once
* when application is relaunched.
* If boolean preference has been set before, and value is not default, migrate to the new
* corresponding string value
* If boolean preference has been set before, but value is default, simply remove it
* #param context application context
* TODO remove once all users migrated
*/
public static void migrate(Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
for (BoolToStringPref pref : PREF_MIGRATION) {
if (pref.isChanged(context, sp)) {
editor.putString(context.getString(pref.newKey), context.getString(pref.newValue));
}
if (pref.hasOldValue(context, sp)) {
editor.remove(context.getString(pref.oldKey));
}
}
editor.apply();
}
public static void applyTheme(ContextThemeWrapper contextThemeWrapper) {
if (Preferences.darkThemeEnabled(contextThemeWrapper)) {
contextThemeWrapper.setTheme(R.style.AppTheme_Blue);
}
}
private static boolean darkThemeEnabled(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getString(context.getString(R.string.pref_theme),
context.getString(R.string.pref_theme_value_red))
.equals(context.getString(R.string.pref_theme_value_blue));
}
private static class BoolToStringPref {
private final int oldKey;
private final boolean oldDefault;
private final int newKey;
private final int newValue;
private BoolToStringPref(#StringRes int oldKey, boolean oldDefault,
#StringRes int newKey, #StringRes int newValue) {
this.oldKey = oldKey;
this.oldDefault = oldDefault;
this.newKey = newKey;
this.newValue = newValue;
}
private boolean isChanged(Context context, SharedPreferences sp) {
return hasOldValue(context, sp) &&
sp.getBoolean(context.getString(oldKey), oldDefault) != oldDefault;
}
private boolean hasOldValue(Context context, SharedPreferences sp) {
return sp.contains(context.getString(oldKey));
}
}
}
Checkout that demo, It will helps you to understand more.
Dynamic themes using style.xml
Here is my code
Style.xml
<resources>
<style name="AppTheme.Base.Green" parent="AppTheme.Green">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.Base.Green.Dark" parent="AppTheme.Green">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg_black</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.Base.Purple" parent="AppTheme.Purple">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.Base.Purple.Dark" parent="AppTheme.Purple">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg_black</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- Base application themes. -->
<style name="ThemeApp.Green" parent="AppTheme.Base.Green"/>
<style name="ThemeApp.Green.Dark" parent="AppTheme.Base.Green.Dark"/>
<style name="ThemeApp.Purple" parent="AppTheme.Base.Purple"/>
<style name="ThemeApp.Purple.Dark" parent="AppTheme.Base.Purple.Dark"/>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#android:color/white</item>
</style>
</resources>
themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme.Green" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#color/primary_green</item>
<item name="colorPrimaryDark">#color/primary_dark_green</item>
<item name="colorAccent">#color/accent_green</item>
<item name="colorControlHighlight">#color/primary_green</item>
<item name="android:textColorPrimary">#color/primary_text</item>
<item name="android:textColorSecondary">#color/secondary_text</item>
</style>
<style name="AppTheme.Purple" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#color/primary_purple</item>
<item name="colorPrimaryDark">#color/primary_dark_purple</item>
<item name="colorAccent">#color/accent_purple</item>
<item name="colorControlHighlight">#color/primary_purple</item>
<item name="android:textColorPrimary">#color/primary_text</item>
<item name="android:textColorSecondary">#color/secondary_text</item>
</style>
</resources>
v21/style.xml
<resources>
<style name="AppTheme.Base.Green" parent="AppTheme.Green">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:navigationBarColor">#color/primary_green</item>
</style>
<style name="AppTheme.Base.Green.Dark" parent="AppTheme.Green">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg_black</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:navigationBarColor">#color/primary_green</item>
</style>
<style name="AppTheme.Base.Purple" parent="AppTheme.Purple">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:navigationBarColor">#color/primary_purple</item>
</style>
<style name="AppTheme.Base.Purple.Dark" parent="AppTheme.Purple">
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
<item name="windowActionModeOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#color/activity_bg_black</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:navigationBarColor">#color/primary_purple</item>
</style>
<!-- Base application themes. -->
<style name="ThemeApp.Green" parent="AppTheme.Base.Green"/>
<style name="ThemeApp.Green.Dark" parent="AppTheme.Base.Green.Dark"/>
<style name="ThemeApp.Purple" parent="AppTheme.Base.Purple"/>
<style name="ThemeApp.Purple.Dark" parent="AppTheme.Base.Purple.Dark"/>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#android:color/white</item>
</style>
<!-- <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />-->
</resources>
method for change Theme runtime
private void setAppTheme() {
if (!MainController.preferenceGetString(Theme_Current, "").equals("")) {
if (MainController.preferenceGetString(Theme_Current, "").equals("Green")) {
setTheme(R.style.ThemeApp_Green);
} else if (MainController.preferenceGetString(Theme_Current, "").equals("Green_Dark")) {
setTheme(R.style.ThemeApp_Green_Dark);
} else if (MainController.preferenceGetString(Theme_Current, "").equals("Purple_Dark")) {
setTheme(R.style.ThemeApp_Purple_Dark);
} else if (MainController.preferenceGetString(Theme_Current, "").equals("Purple")) {
setTheme(R.style.ThemeApp_Purple);
}
} else {
setTheme(R.style.ThemeApp_Green);
}
}
after execute this method restart your activity needed
full source code
https://github.com/rkoshti/DynamicMaterialTheme

Pass two Activities with Fade Animation Automatically

I have one activity that show my logo and i want change to second activity after that two seconds automatically.
I have done this but it doesn´t apply the effect.
Logo.java
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.logo_layout);
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
Intent i = new Intent(Logo.this, Loggin.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(Logo.this);
startActivity(i, options.toBundle());
finishAfterTransition();
}
}, TIME);
}
res/transition/my_trasition.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<fade
android:duration="1000">
</fade>
</transitionSet>
res/values/styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppFullScreen" parent="#style/Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:windowEnterTransition">#transition/transicion</item>
<item name="android:windowExitTransition">#transition/transicion</item>
<item name="android:windowAllowEnterTransitionOverlap">false</item>
<item name="android:windowAllowReturnTransitionOverlap">false</item>
</style>

Categories