How to _really_ programmatically change primary and accent color in Android Lollipop?
Themes are immutable, you can't.
How to programmatically change the primary color in Android L?
You can, of course, implement custom subclasses of View that have methods for setting colors.
You can also define multiple themes with you various color schemes.
Views look up theme information from the context when they are created. So to change the styles applied from a theme you will have to recreate your view hierarchy with a context that uses the right theme.
One way to do that, is to create a new ContextThemeWrapper and then get a LayoutInflator that uses that theme wrapper, remove the old version of your layout and re-inflate your layout.
Roughly:
ContextThemeWrapper themeWrapper = new ContextThemeWrapper(this, R.style.AppThemeWithColorScheme2);
LayoutInflater layoutInflater = LayoutInflater.from(themeWrapper);
viewContainer.removeAllViews();
layoutInflater.inflate(R.layout.my_layout, viewContainer, true );
If you are using Action Bar, that may be a bit more tricky, because the Action Bar is created once per activity.
How to apply colors programmatically to app theme?
Define your custom theme inside style.xml
and use that inside your activity
style.xml
<style name="CustomTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/your_custom_color</item>
<item name="colorPrimaryDark">@color/your_custom_color_2</item>
<item name="android:navigationBarColor">@color/your_custom_colot_3</item>
</style>
And use that theme inside your activity
public void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.CustomTheme); //here your custom theme
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
Let the user set light or dark theme plus accent color
The approach I have used is that, keep your colors in an array and let users select the color and store the index of selected color in preferences. So once when the activity is loading read the stored color and set the color accordingly
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(this,colors.getResourceId(chapter_key-1, 0)));
}
package com.**********.app.customViews;
/**
* Created by pakistantechhouse on 18/02/2017.
*/
import android.content.Context;
import android.graphics.Canvas;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
import com.**********.app.R;
public class CRelativeLayout extends RelativeLayout {
public CRelativeLayout(Context context) {
super(context);
if (!isInEditMode()) {
//TODO get your color here from the preferences and apply to the view
this.setBackgroundColor(ContextCompat.getColor(context, R.color.colorPrimary));
}
}
public CRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
//TODO get your color here from the preferences and apply to the view
this.setBackgroundColor(ContextCompat.getColor(context, R.color.colorPrimary));
}
}
public CRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (!isInEditMode()) {
//TODO get your color here from the preferences and apply to the view
this.setBackgroundColor(ContextCompat.getColor(context, R.color.colorPrimary));
}
}
protected void onDraw (Canvas canvas) {
super.onDraw(canvas);
}
}
changing app material theme colorPrimaryDark programatically in android?
There is no way such as per current available methods of android sdk. So Instead of changing colorPrimaryDark attribute programatically, I am applying different themes for different activities
Dynamically change android's accent color
I found the solution!
- All you have to put accent (or any other) color for light theme in
MyApp.Android\Resources\values\colors.xml
and for dark theme inMyApp.Android\Resources\values-night\colors.xml
. Then reference that color by name in your theme instyles.xml
<item name="colorAccent">@color/colorAccent</item>
.
Now, when device would switch to dark theme accent color also would change. - Now. What if you have manual theme control in your app? You can force Android to display color for light or dark theme. Add similar interface to the shared project:
namespace MyApp.Core.Models.InterplatformCommunication
{
public interface INightModeManager
{
NightModeStyle DefaultNightMode { get; set; }
}
public enum NightModeStyle
{
/// <summary>
/// An unspecified mode for night mode.
/// </summary>
Unspecified = -100,
/// <summary>
/// Mode which uses the system's night mode setting to determine if it is night or not.
/// </summary>
FollowSystem = -1,
/// <summary>
/// Night mode which uses always uses a light mode, enabling non-night qualified resources regardless of the time.
/// </summary>
No = 1,
/// <summary>
/// Night mode which uses always uses a dark mode, enabling night qualified resources regardless of the time.
/// </summary>
Yes = 2,
/// <summary>
/// Night mode which uses a dark mode when the system's 'Battery Saver' feature is enabled, otherwise it uses a 'light mode'.
/// </summary>
AutoBattery = 3
}
}
- Add this implementation in Android project. Setting
AppCompatDelegate.DefaultNightMode
forces the app to load resources for light or dark theme without restarting the app.
[assembly: Xamarin.Forms.Dependency(typeof(NightModeManager))]
namespace MyApp.Droid.Dependences
{
public class NightModeManager : INightModeManager
{
public NightModeStyle DefaultNightMode
{
get => (NightModeStyle)AppCompatDelegate.DefaultNightMode;
set => AppCompatDelegate.DefaultNightMode = (int)value;
}
}
}
- Add this logic when changing theme of your app (
AppTheme
is a custom enum):
private static void UpdateNativeStyle(AppTheme selectedTheme)
{
NightModeStyle style = selectedTheme switch
{
AppTheme.Dark => NightModeStyle.Yes,
AppTheme.Light => NightModeStyle.No,
AppTheme.FollowSystem => NightModeStyle.FollowSystem,
_ => throw new InvalidOperationException("Unsupported theme"),
};
var nightModeManager = DependencyService.Get<INightModeManager>();
nightModeManager.DefaultNightMode = style;
}
More info about this:
- https://medium.com/androiddevelopers/appcompat-v23-2-daynight-d10f90c83e94
- https://www.journaldev.com/19352/android-daynight-theme-night-mode
Related Topics
How to Implement Multi-Select in Recyclerview
Startforeground Fail After Upgrade to Android 8.1
How to Automatically Update Application on Android
How to Set Custom Header in Volley Request
Android - How to Receive Broadcast Intents Action_Screen_On/Off
This Version of the Application Is Not Configured for Billing Through Google Play
Android Preventing Double Click on a Button
Android P - 'Sqlite: No Such Table Error' After Copying Database from Assets
Media Player Called in State 0, Error (-38,0)
Use Picasso to Get a Callback with a Bitmap
Passing Data Between Fragments to Activity
Strange Behavior with Android Orientation Sensor
How to Add a Textview to a Linearlayout Dynamically in Android
How to Pass Arraylist of Objects from One to Another Activity Using Intent in Android
How to Dynamically Set the Position of View in Android
How to Import Existing Android Project into Eclipse