I have read that there is a way to have a values-night and a values folder. But how to change from values to values-night before starting ,because of my splash screen. I know that there must be a way to have a dark and light themed splash screen ,because of WhatsApp.
How to change to values-night before Splash Screen is shown?
Try below dark mode code which I am use.
Step - 1
First of create night folder into your resource file like below image(i.e. values-night)
Step - 2
Create styles,strings and colors xml file for night mode same as below image and add your night mode color,string and style which you want to show in your app when night mode was apply.
For better user experience add window Animation in your style.
values --> style.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>
</style>
<style name="NoActionBarAppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- Add this theme where you change mode -->
<style name="NoActionBarWithChangeTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- This will set the fade in animation on your change theme activity by default -->
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#anim/fade_in</item>
<item name="android:windowExitAnimation">#anim/fade_out</item>
</style>
</resources>
values-night --> style.xml
<!-- Base application theme. values-night.xml -->
<style name="NoActionBarAppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- Add this theme where you change mode -->
<style name="NoActionBarWithChangeTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- This will set the fade in animation on your change activity by default -->
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#anim/fade_in</item>
<item name="android:windowExitAnimation">#anim/fade_out</item>
</style>
fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="#android:anim/linear_interpolator">
<alpha
android:duration="2000"
android:fromAlpha="0.0"
android:toAlpha="1.0">
</alpha>
</set>
fade_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<alpha
android:duration="2000"
android:fromAlpha="1.0"
android:toAlpha="0.0" >
</alpha>
</set>
Step - 3
Add this below code in your splash screen if you want to set night mode as per device mode first time when application installed.
#Override
protected void onCreate(Bundle savedInstanceState) {
if (!CommonUtils.isToogleEnabled(SplashActivity.this)) {
if (CommonUtils.isDarkMode(SplashActivity.this)) {
CommonUtils.setIsNightModeEnabled(SplashActivity.this, true);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
CommonUtils.setIsNightModeEnabled(SplashActivity.this, false);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
} else {
if (CommonUtils.isNightModeEnabled(SplashActivity.this)) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
super.onCreate(savedInstanceState);
...
//your code
}
Step - 4
Add this below code in your all activity
#Override
protected void onCreate(Bundle savedInstanceState) {
if (CommonUtils.isNightModeEnabled(MainActivity.this)) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
super.onCreate(savedInstanceState);
...
//your code
}
Step - 5
Change mode using below code
private WeakReference<Activity> mActivity;
binding.imgNightMode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mActivity = new WeakReference<Activity>(MainActivity.this);
CommonUtils.setIsToogleEnabled(MainActivity.this, true);
if (CommonUtils.isNightModeEnabled(MainActivity.this)) {
CommonUtils.setIsNightModeEnabled(MainActivity.this, false);
mActivity.get().recreate();
} else {
CommonUtils.setIsNightModeEnabled(MainActivity.this, true);
mActivity.get().recreate();
}
}
});
Below methods are CommonUtils.
private static final String NIGHT_MODE = "NIGHT_MODE";
private static final String TOOGLE = "TOOGLE";
public static boolean isNightModeEnabled(Context context) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
return mPrefs.getBoolean(NIGHT_MODE, false);
}
public static void setIsNightModeEnabled(Context context, boolean isNightModeEnabled) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(NIGHT_MODE, isNightModeEnabled);
editor.apply();
}
public static void setIsToogleEnabled(Context context, boolean isToogleEnabled) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(TOOGLE, isToogleEnabled);
editor.apply();
}
public static boolean isToogleEnabled(Context context) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
return mPrefs.getBoolean(TOOGLE, false);
}
public static boolean isDarkMode(Activity activity) {
return (activity.getResources().getConfiguration()
.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}
I hope this can help you!
Thank You.
Related
How to change the App theme dynamically in android. I have an app with many users, when users log in, as per requirements I have to change the app theme dynamically.
Try this
styles.xml
<style name="lightTheme">
<item name="android:textViewStyle">#style/LightStyledTextView</item>
<item name="android:windowAnimationStyle">#null</item>
<item name="actionOverflowMenuStyle">#style/LightStyledOptionsMenu</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="darkTheme">
<item name="android:textViewStyle">#style/DarkStyledTextView</item>
<item name="android:windowAnimationStyle">#null</item>
<item name="actionOverflowMenuStyle">#style/DarkStyledOptionsMenu</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="LightStyledTextView" parent="Widget.AppCompat.TextView.SpinnerItem">
<item name="android:textColor">#color/black</item>
</style>
<style name="DarkStyledTextView" parent="Widget.AppCompat.TextView.SpinnerItem">
<item name="android:textColor">#color/white</item>
</style>
<!-- Menu Styles-->
<style name="LightStyledOptionsMenu" parent="ThemeOverlay.AppCompat.Light">
<item name="overlapAnchor">false</item>
<item name="android:popupBackground">#color/white</item>
<item name="android:textColor">#color/blue_grey</item>
</style>
<style name="DarkStyledOptionsMenu" parent="ThemeOverlay.AppCompat.Dark">
<item name="overlapAnchor">false</item>
<item name="android:popupBackground">#color/blue_grey</item>
<item name="android:textColor">#color/white</item>
</style>
create this in BaseActivity and call in onCreate method
public void updateTheme()
{
if (Utility.getTheme(getApplicationContext()))
{
setTheme(R.style.darkTheme);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
else
{
setTheme(R.style.lightTheme);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
}
Utility.java
public static void setTheme(Context context, boolean theme)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putBoolean(context.getString(R.string.prefs_theme_key), theme).apply();
}
public static Boolean getTheme(Context context)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(R.string.prefs_theme_key), false);
}
and in any Activity use any component to change theme, in this case Switch
Switch darkModeSwitch = findViewById(R.id.darkModeSwitch);
darkModeSwitch.setChecked(Utility.getTheme(this));
darkModeSwitch.setOnCheckedChangeListener((compoundButton, checked) ->
{
Utility.setTheme(getApplicationContext(), checked);
});
I am developing Day/Night feature in my app so I read those documents and start developing it.
It's working fine with default value in Day or Night
with deligate method AppCompatDelegate.setDefaultNightMode(*).
For customize night theme color I create values-night folder and inside I create colors.xml file like below.
res -> values -> colors.xml
res -> values-night -> colors.xml
After I place that color but not applying in Night theme! Its very strange why value-night colors is not applying always its showing default night color?
I have researched some but can't find the solution.
Note: Recreate activity is resolved my issue but I don't want to recreate
Here is my build.gradle file
Advance Thanks.
Try below dark mode code which I am use.
Step - 1
First of create night folder into your resource file like below image(i.e. values-night)
Step - 2
Create styles,strings and colors xml file for night mode same as below image and add your night mode color,string and style which you want to show in your app when night mode was apply.
For better user experience add window Animation in your style.
values --> style.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>
</style>
<style name="NoActionBarAppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- Add this theme where you change mode -->
<style name="NoActionBarWithChangeTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- This will set the fade in animation on your change theme activity by default -->
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#anim/fade_in</item>
<item name="android:windowExitAnimation">#anim/fade_out</item>
</style>
</resources>
values-night --> style.xml
<!-- Base application theme. values-night.xml -->
<style name="NoActionBarAppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- Add this theme where you change mode -->
<style name="NoActionBarWithChangeTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/white</item>
<item name="colorPrimaryDark">#color/white</item>
<item name="colorAccent">#color/main_click_txt</item>
<item name="android:windowAnimationStyle">#style/WindowAnimationTransition</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>
</style>
<!-- This will set the fade in animation on your change activity by default -->
<style name="WindowAnimationTransition">
<item name="android:windowEnterAnimation">#anim/fade_in</item>
<item name="android:windowExitAnimation">#anim/fade_out</item>
</style>
fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="#android:anim/linear_interpolator">
<alpha
android:duration="2000"
android:fromAlpha="0.0"
android:toAlpha="1.0">
</alpha>
</set>
fade_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<alpha
android:duration="2000"
android:fromAlpha="1.0"
android:toAlpha="0.0" >
</alpha>
</set>
Step - 3
Add this below code in your splash screen if you want to set night mode as per device mode first time when application installed.
#Override
protected void onCreate(Bundle savedInstanceState) {
if (!CommonUtils.isToogleEnabled(SplashActivity.this)) {
if (CommonUtils.isDarkMode(SplashActivity.this)) {
CommonUtils.setIsNightModeEnabled(SplashActivity.this, true);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
CommonUtils.setIsNightModeEnabled(SplashActivity.this, false);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
} else {
if (CommonUtils.isNightModeEnabled(SplashActivity.this)) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
super.onCreate(savedInstanceState);
...
//your code
}
Step - 4
Add this below code in your all activity
#Override
protected void onCreate(Bundle savedInstanceState) {
if (CommonUtils.isNightModeEnabled(MainActivity.this)) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
super.onCreate(savedInstanceState);
...
//your code
}
Step - 5
Change mode using below code
private WeakReference<Activity> mActivity;
binding.imgNightMode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mActivity = new WeakReference<Activity>(MainActivity.this);
CommonUtils.setIsToogleEnabled(MainActivity.this, true);
if (CommonUtils.isNightModeEnabled(MainActivity.this)) {
CommonUtils.setIsNightModeEnabled(MainActivity.this, false);
mActivity.get().recreate();
} else {
CommonUtils.setIsNightModeEnabled(MainActivity.this, true);
mActivity.get().recreate();
}
}
});
Below methods are CommonUtils.
private static final String NIGHT_MODE = "NIGHT_MODE";
private static final String TOOGLE = "TOOGLE";
public static boolean isNightModeEnabled(Context context) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
return mPrefs.getBoolean(NIGHT_MODE, false);
}
public static void setIsNightModeEnabled(Context context, boolean isNightModeEnabled) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(NIGHT_MODE, isNightModeEnabled);
editor.apply();
}
public static void setIsToogleEnabled(Context context, boolean isToogleEnabled) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean(TOOGLE, isToogleEnabled);
editor.apply();
}
public static boolean isToogleEnabled(Context context) {
SharedPreferences mPrefs = context.getSharedPreferences("MY_PREF", MODE_PRIVATE);
return mPrefs.getBoolean(TOOGLE, false);
}
public static boolean isDarkMode(Activity activity) {
return (activity.getResources().getConfiguration()
.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}
I hope this can help you!
Thank You.
Change appcompat dependency from 1.1.0 to 1.0.0, There is some issue to update resource in 1.1.0. This trick worked for me.
implementation 'androidx.appcompat:appcompat:1.1.0'//Remove
implementation 'androidx.appcompat:appcompat:1.0.0' // Add
Hope this will help you!!
I want the floating label of TextInputLayouts to change colour (e.g. to red) when there is an error. I can change the colour of the error text, but it has no effect on the appearance of the floating label (unlike someone in some other thread claimed). I couldn't use selectors for the hint colour to solve this problem either, as there does not seem to be a state defined for errors. Does anyone have any idea how to do this without having to manually program the change on error events/create a new java class (with EditText as parent)?
Here are the stylings I defined:
<style name="EditTextFloatingLabel" parent="#android:style/TextAppearance">
<item name="android:textSize">#dimen/textsize_caption_small</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:textColor">#color/input_text_color</item>
</style>
<style name="EditTextErrorText" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/error_color</item>
</style>
<style name="EditTextLayout">
<item name="android:textColorHint">#color/placeholder_color</item>
<item name="android:background">#drawable/input_field_background</item>
<item name="android:paddingBottom">#dimen/default_margin_bottom</item>
<item name="android:paddingStart">#dimen/default_margin_left</item>
<item name="android:paddingEnd">#dimen/default_margin_right</item>
</style>
<style name="EditTextTheme">
<item name="android:imeOptions">actionDone</item>
<item name="android:maxLines">1</item>
<item name="colorControlNormal">#color/primary_line_color</item>
<item name="colorControlActivated">#color/nordea_blue</item>
<item name="android:colorControlHighlight">#color/error_color</item>
<item name="android:textColorPrimary">#color/input_field_text</item>
<item name="android:textSize">#dimen/textsize_caption</item>
<item name="android:textColorHint">#color/placeholder_color</item>
</style>
<style name="EditText">
<item name="android:theme">#style/EditTextTheme</item>
<item name="android:textCursorDrawable">#drawable/cursor_blue</item>
<item name="android:paddingTop">#dimen/default_padding_top</item>
<item name="android:paddingStart">#dimen/payment_text_input_padding</item>
</style>
Usage:
<android.support.design.widget.TextInputLayout
android:id="#+id/input_field_error_wrapper_light"
style="#style/EditTextLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/testlogin_text_input_end_padding"
android:layout_marginStart="#dimen/testlogin_text_input_start_padding"
android:paddingTop="#dimen/default_padding_top"
app:hintTextAppearance="#style/EditTextFloatingLabel"
app:errorTextAppearance="#style/EditTextErrorText"
app:errorEnabled="true">
<EditText
android:id="#+id/input_field_light_error"
style="#style/EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#Input Field Disabled Light"
android:imeOptions="actionDone"
/>
</android.support.design.widget.TextInputLayout>
And this is what I see:
As I needed to perform some other actions as well when the layout was in error state, I decided to go with the solution of creating a custom error state and a custom TextInputLayout which can enter this state.
Code:
Defining the new error state in res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<!-- custom states -->
<declare-styleable name="ErrorState">
<attr name="state_error" format="boolean" />
</declare-styleable>
</resources>
ErrorStateTextInputLayout class:
public class ErrorStateTextInputLayout extends TextInputLayout {
private boolean hasError = false;
private static final int[] ERROR_STATE = new int[]{R.attr.state_error};
public ErrorStateTextInputLayout(Context context) {
super(context);
}
public ErrorStateTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ErrorStateTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
int[] state = super.onCreateDrawableState(extraSpace + 1);
if (hasError) {
mergeDrawableStates(state, ERROR_STATE);
}
return state;
}
#Override
public void setError(#Nullable CharSequence error) {
if (error == null) {
setHasError(false);
} else {
setHasError(true);
}
super.setError(error);
}
public void setHasError(boolean error) {
this.hasError = error;
refreshDrawableState();
}
}
Selector for setting the hint text colour:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:color="#color/disabled_text_color" android:state_enabled="false" />
<item android:color="#color/error_color" app:state_error="true" />
<item android:color="#color/input_text_color" android:state_focused="true" />
<item android:color="#color/placeholder_color" />
</selector>
This blog post helped me a lot: http://code.neenbedankt.com/example-of-custom-states-in-android-components/
Try this..solid_red floating color.....
<style name="TextLabelInput" parent="TextAppearance.AppCompat">
<!-- Hint color and label color in FALSE state -->
<item name="android:textColorHint">#color/solid_red</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">#color/solid_red</item>
<item name="android:duration">200</item>
<item name="android:textColorHighlight">#color/solid_red</item>
<!-- Label color in TRUE state and bar color FALSE and TRUE State -->
<item name="colorAccent">#color/solid_red</item>
<item name="colorControlNormal">#color/solid_red</item>
<item name="colorControlActivated">#color/solid_red</item>
<item name="colorPrimary">#color/solid_red</item>
<item name="colorPrimaryDark">#color/solid_red</item>
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
app:errorTextAppearance="#style/TextLabelInput"
>
hint text color manage over your main theme
which are colorPrimary and colorAccent
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
I want to be able to change the background color of my app so that whenever i want to change the color during runtime, i can just press a button in the app to change the background color. After the changing the color i want that it should stay there whenever i open the app again. Also i would like to know how to change the color of other activities while I am in another activity.
Thanks in advance.
my colors.xml:
<resources>
<color name="original">#25383C</color>
<color name="grey">#484849</color>
<color name="red">#881A27</color>
<color name="orange">#ffa500</color>
<color name="yellow">#CDE707</color>
<color name="green">#00ff00</color>
<color name="aqua">#00FFCC</color>
<color name="marine">#0C0C84</color>
<color name="purple">#630A86</color>
<color name="silver">#c0c0c0</color>
styles.xml(it has themes):
<resources>
<style name="original">
<item name="android:background">#25383C</item>
</style>
<style name="grey">
<item name="android:background">#484849</item>
</style>
<style name="red">
<item name="android:background">#881A27</item>
</style>
<style name="orange">
<item name="android:background">#ffa500</item>
</style>
<style name="yellow">
<item name="android:background">#CDE707</item>
</style>
<style name="green">
<item name="android:background">#00ff00</item>
</style>
<style name="aqua">
<item name="android:background">#00FFCC</item>
</style>
<style name="marine">
<item name="android:background">#0C0C84</item>
</style>
<style name="purple">
<item name="android:background">#630A86</item>
</style>
<style name="silver">
<item name="android:background">#c0c0c0</item>
</style>
You can use Android Shared Preferences to remember the selected background color for the app.So every time you open the app you can check the value of the shared preference and apply the color accordingly.
Use a common base activity class that all the other activities will derive and in the "OnCreate" and "OnResume" methods write the code to read shared preference value and apply back ground color.This way when you open any activity selected background color will be applied.
Try below code, it is tested and working.
BaseActivity Class
public class BaseActivity extends ActionBarActivity {
private static final String PREFS_NAME="color_settings";
SharedPreferences prefsReader = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
prefsReader=getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
#Override
public void setContentView(int layoutResID) {
super.setContentView(layoutResID);
setBackgroundColor();
}
protected void setBackgroundColor()
{
int background_resource_id= prefsReader.getInt("background_resource_id",0);
View bgView= findViewById(R.id.main_container);
bgView.setBackgroundColor(getResources().getColor(background_resource_id));
}
protected void setCurrentBackgroundColor(int colorResourceId)
{
SharedPreferences.Editor editor=getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit();
editor.putInt("background_resource_id", colorResourceId);
editor.commit();
}
}
Activity Class
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//save the color resource value in shared pref
setCurrentBackgroundColor(R.color.red);
setContentView(R.layout.activity_main);
}
}
Colors.xml color list
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="blue" type="color">#FF33B5E5</item>
<item name="purple" type="color">#FFAA66CC</item>
<item name="green" type="color">#FF99CC00</item>
<item name="orange" type="color">#FFFFBB33</item>
<item name="red" type="color">#FFFF4444</item>
<item name="darkblue" type="color">#FF0099CC</item>
<item name="darkpurple" type="color">#FF9933CC</item>
<item name="darkgreen" type="color">#FF669900</item>
<item name="darkorange" type="color">#FFFF8800</item>
<item name="darkred" type="color">#FFCC0000</item>
</resources>
For doing such thing you can maintain a database to store the values for the different colors.
Now, Whenever you press the button after choosing the particular color for your application you just have to update the color value in your database.
In onCreate() method of your MainActivity(Launcher Activity), You just have to retrieve the color value from the field of database and can set it in your application.
I created an app and It has multiple themes and it changes dynamically. I mean in run-time user can choose different themes. so that UI components color changes in runtime. I got stuck in a strange problem. Problem is status bar color is not changing according to theme. statusBar always stays in initial theme color.
values-v21/style.xml is as below
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<item name="colorAccent">#color/accent</item>
<item name="android:textColorPrimary">#color/primary_text</item>
<item name="android:icon">#color/icons</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
values-v21/themes.xml is as below
===================================
<resources>
<style name="AppThemeRed" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#F44336</item>
<item name="colorPrimaryDark">#D32F2F</item>
<item name="colorAccent">#FFCDD2</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:icon">#color/icons</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
<style name="AppThemeAmber" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#FFC107</item>
<item name="colorPrimaryDark">#FFA000</item>
<item name="colorAccent">#FFEB3B</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:icon">#color/icons</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
<style name="AppThemeBlue" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#3F51B5</item>
<item name="colorPrimaryDark">#303F9F</item>
<item name="colorAccent">#448AFF</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
<style name="AppThemePurple" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#9C27B0</item>
<item name="colorPrimaryDark">#7B1FA2</item>
<item name="colorAccent">#7C4DFF</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
<style name="AppThemeYellow" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#FFEB3B</item>
<item name="colorPrimaryDark">#FBC02D</item>
<item name="colorAccent">#CDDC39</item>
<item name="android:textColorPrimary">#FFFFFF</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
</resources>
when user selects a theme from theme selection dialog i calling a function and setting theme for that activity, also recreating activity.
public static void onActivityCreateSetTheme(Activity activity)
{
switch (sTheme)
{
case 0:
activity.setTheme(R.style.AppThemeRed);
break;
case 1:
activity.setTheme(R.style.AppThemeAmber);
break;
default:
case 2:
activity.setTheme(R.style.AppTheme);
break;
case 3:
activity.setTheme(R.style.AppThemeBlue);
break;
case 4:
activity.setTheme(R.style.AppThemePurple);
break;
case 5:
activity.setTheme(R.style.AppThemeYellow);
break;
}
}
I am using NavigationView in drawer and drawer is coming below status bar no problem with that. But status bar is not picking up current theme's primaryDark-color. It always takes Default theme(startup theme) color only.
Setting the theme via setTheme(int resId) in the onCreate() method won't have any effect on the StatusBar since it is not part of the Activity itself afaik.
So in order to achieve the desired effect you need to do it programatically. Here's a snippet which resolves the R.attr.colorPrimaryDark and sets it for the StatusBar if the SDK-Level is above 21:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
setContentView(R.layout.activity_management);
// Further code
}
private void init(){
// Set the Theme
setTheme(R.style.MyAppTheme);
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
getWindow().setStatusBarColor(getAttributeColor(R.attr.colorPrimaryDark));
}
}
// Resolve the given attribute of the current theme
private int getAttributeColor(int resId) {
TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(resId, typedValue, true);
int color = 0x000000;
if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) {
// resId is a color
color = typedValue.data;
} else {
// resId is not a color
}
return color;
}
Edit
This approach obviously overwrites the color which is set via android:statusBarColor. So if you're using a NavigationDrawer and you want that the Drawer goes "under" the StatusBar you have to set the StatusBar color to transparent manually as soon as the Drawer is opened:
Example
actionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar,
R.string.open_drawer_accessibility_desc,
R.string.close_drawer_accessibility_desc) {
#SuppressLint("NewApi")
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(
getResources().getColor(android.R.color.transparent));
}
}
/** Called when a drawer has settled in a completely open state. */
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
/** Called when a drawer has settled in a completely closed state. */
#Override
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
};
}