How to give the user the possibility to switch between different colors skin in an app
Asked Answered
O

2

7

I want to give the user the opportunity to select which color skin they'll have in my app. For example, I would implement a black skin with black colours with different tonalities and also a white skin with with tonalities.

What would be the best approach to achieve this?

For example I know that there is a colors.xml file in Android that should contain the colours of your app. Would be a way to have two colors files or something and to use one or other depending of user selection? Maybe a styles.xml file?

My layout:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <RelativeLayout
        android:id="@+id/main_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v4.view.ViewPager
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v4.view.PagerTitleStrip
                android:id="@+id/pager_title_strip"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="top"
                android:paddingTop="4dp"
                android:paddingBottom="4dp"
                style="@style/CustomPagerTitleStrip"/>
        </android.support.v4.view.ViewPager>
    </RelativeLayout>
    <!-- The navigation drawer -->
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer_menu"
        style="@style/NavigationDrawerStyle"/>
</android.support.v4.widget.DrawerLayout>

My styles.xml file:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="actionBarTheme">@style/CustomActionBar</item>
        <item name="android:textColor">@color/colorFontMenus</item>
        <item name="itemTextColor">@color/colorFontMenus</item>
        <item name="itemIconTint">@color/colorFontMenus</item>
    </style>

    <style name="CustomActionBar">
        <!-- title text color -->
        <item name="android:textColorPrimary">@color/colorFontMenus</item>
        <!-- subtitle text color -->
        <item name="android:textColorSecondary">?android:textColorPrimary</item>
        <!-- action menu item text color -->
        <item name="actionMenuTextColor">?android:textColorPrimary</item>
        <!-- action menu item icon color - only applies to appcompat-v7 icons :( -->
        <item name="colorControlNormal">?android:textColorPrimary</item>
    </style>

    <style name="CustomPagerTitleStrip">
        <item name="android:background">@color/mainColorWithAlpha</item>
    </style>

    <style name="CustomTextView">
        <item name="android:textColor">@color/colorFontContent</item>
    </style>

    <style name="CustomScrollBar">
        <item name="android:scrollbarThumbVertical">@drawable/scrollbar_green</item>
    </style>

    <style name="CustomDrawerHeader">
        <item name="android:background">@drawable/drawer_header_background_green</item>
    </style>

    <style name="NavigationDrawerStyle">
        <item name="android:background">@color/colorPrimaryDark</item>
   </style>

</resources>
Odessa answered 13/7, 2016 at 10:32 Comment(3)
I don't have all the details to post a proper answer, but just to give a guidance: use it with a style/theme. Here u can find how to change between them on runtime #19125663Joerg
@Odessa actually i am doing it in my application but i dont change entire theme. I just change Statusbar color,Toolbar color , Fab color, and any other color whatever i want programmatically based on a color value in SharedPreferences. If you want i can give you my code. But if you want to check sth i can suggest you look this : android-change-app-theme-runtimeStylus
@ NullPointerException I've written an explanation on how to get this, also posted some sources so you can have a broader knowledge on the matter.Shroyer
J
4

Regarding to @Joaquim Ley's answer we can change Theme before super.onCreate() .

In my app(at work) my styles.xml :

This is my default theme

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="android:colorAccent">@color/colorPrimary</item>
    <item name="android:statusBarColor">@color/colorPrimaryDark</item>
    <item name="android:colorFocusedHighlight">@color/colorPrimary</item>
    <item name="android:colorControlNormal">@color/amber_300</item>
    <item name="android:colorControlActivated">@color/amber_300</item>
    <item name="android:colorControlHighlight">@color/colorControlHighlight</item>
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    <item name="android:windowTranslucentStatus">false</item>
    <item name="actionBarItemBackground">?attr/selectableItemBackground</item>
    <item name="colorControlHighlight">@color/colorControlHighlight</item>
    <item name="android:windowContentTransitions">true</item>
    <!-- Customize your theme here. -->
</style>

And this is my Green Theme :

<style name="AppTheme.Green" parent="AppTheme">
    <item name="colorPrimary">@color/green_500</item>
    <item name="colorPrimaryDark">@color/green_700</item>
    <item name="android:colorAccent">@color/green_300</item>
    <item name="android:statusBarColor">@color/green_700</item>
    <item name="android:colorFocusedHighlight">@color/green_500</item>
    <item name="android:colorControlNormal">@color/green_300</item>
    <item name="android:colorControlActivated">@color/green_300</item>
</style>

When changing theme :

@Override
protected void onCreate(Bundle savedInstanceState) {
    mPrefs=getSharedPreferences(getResources().getString(R.string.preference_name),MODE_PRIVATE);
    mEditor=mPrefs.edit();
    mEditor.apply();
    defaultColor=mPrefs.getInt(getResources().getString(R.string.default_color),0);
    //you can do some switch case or if else of defaultColor and change theme
    setTheme(R.style.AppTheme_Green);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_voice_record);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
}

This is my first app in work, but in my personal app i created a BaseActivity and created a method handleColor(int color,int darkcolor). But this won't change entire theme just Toolbar, StatusBar, NavigationBar and EditText marker and underline colors:

public class BaseActivity extends AppCompatActivity {

public void handleColor(int color,int darkcolor){
    //changing toolbar color
    if(getSupportActionBar()!=null){
        getSupportActionBar().setBackgroundDrawable(new ColorDrawable(color));
    }

    //if bigger than Api 21 change status bar color
    if(isLolipop()){
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(darkcolor);
    }
}

public boolean isLolipop(){
    return  Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
  }

}

When changing color i am using Material Dialogs Color Picker. Sample apk : sample.apk and Github: material-dialogs. If you want to see how it looks like i can give you a video of my app.

Colors from : Material Color Palette

Anyways i know 2 different approach , if you like one of them i can explain more.

@Edit : Good news for you, I found this Github repo : app-theme-engine and its working good. You can try sample apk. If you can't import it via gradle try this : compile 'com.github.naman14:app-theme-engine:0.5.1@aar'

Judsen answered 13/7, 2016 at 11:28 Comment(6)
Hi. Thank you. It is possible to switch the used colors using colors.xml file? It whould be munch more efficient than these two approach. For example, using two colors.xml files, or two groups of colors in colors.xml file, with the same names for each color in both groups. Is that possible?Odessa
@Odessa for your first question : I've never seen/heard any developer that uses many colors.xml, for your second question: you can use color names only once. But you can read this page : UiModeManager and try to implementing night mode.Stylus
One more think, some items cannot be changed inside "AppTheme" custom style, and must be changed inside other custom styles, for example CustomActionBar, CustomPagerTitleStrip, CustomScrollBar... etc How do you apply these custom styles?Odessa
@Odessa can you give me some code, I am able to change ScrollView's scrollbar color at runtime (programmatically). But I've never tried CustomActionBar, CustomPagerTitleStrip. If you clarify what you want to do then I'll help you easily.Stylus
Yasin Kaçmaz ofcourse, i edited my question adding my layout. As you can see I'm using custom styles for my view components.Odessa
@Odessa ı've edited my answer, please checkout Edit section, I think it will help you , have a good day !Stylus
S
1

This should be done in the styles/AppTheme.xml

It’s only possible to change the theme of an Activity in the onCreate() method and that to only before super() has been called. Changing the theme is fairly straight forward, something like below should do it:

setTheme(someBooleanFlag ? R.style.AppThemeOne : R.style.AppThemeTwo);

Read more here:

Ali Muzaffar's Medium post on this

Styles and Themes

Material Theme

Shroyer answered 13/7, 2016 at 11:13 Comment(2)
Joaquim Ley some items cannot be changed inside "AppTheme" custom style, and must be changed inside other custom styles, for example CustomActionBar, CustomPagerTitleStri‌​p, CustomScrollBar... etc. How to switch to other skin color to these custom styles? I edited my question adding my styles.xml file and my layout file.Odessa
You can assign a new style with your OtherCustomStyle parent="AppTheme"Shroyer

© 2022 - 2024 — McMap. All rights reserved.