Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change theme color android #154

Open
sindrisig opened this issue Mar 1, 2016 · 17 comments
Open

Change theme color android #154

sindrisig opened this issue Mar 1, 2016 · 17 comments

Comments

@sindrisig
Copy link

Love the plugin, but i was wondering if there is any way to change the background color of the picker for example i'm using the THEME_DEVICE_DEFAULT_LIGHT like in the photo below and it would be awesome if i could change the green to another color
picker

@brudevit
Copy link

brudevit commented Nov 7, 2016

Hello guy,
Did you solve? What did you do?
I have the same problem!

Tks!

@fab971
Copy link

fab971 commented Apr 17, 2017

Hi,
I'm Interesting to know how to do it.
I started to investigate a way to customize the date/timepicker. I'm not a pro android developer but from my research I was thinking to :
1 - add an app style file (.xml) in resources/values that inherite from, let's say, Theme.AppCompat.Light.Dialog
2 - ensure to copy the .xml to android app by using a hook script:
http://stackoverflow.com/questions/29490925/change-android-theme-from-cordova-config-xml http://stackoverflow.com/questions/35511791/adding-drawable-resource-using-cordova
3 - install cordova-custom-config to allow to define theme/style at app level by overwriting colorAccent and/or colorPrimary?

I still lack knowledge of cordova plugins implementation here but I guess the best option might be to write a plugin which do the job without having to set it up "manually".

Could someone give some direction about the best way to implement this feature?

@znegva
Copy link

znegva commented Jan 30, 2018

Howto use a custom android theme with the datepicker-plugin:

Step 1

Generate your custom styles.xml:

<resources>
    <color name="primaryColor">#0277BD</color>
    <color name="primaryColorDark">#004C8C</color>
    <style name="doneoTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar">
        <!-- on startup the background and app-name is shown, we use the same color to see just background.. -->
        <item name="android:textColorPrimary">@color/primaryColorDark</item>
        <item name="android:colorBackground">@color/primaryColorDark</item>

        <!-- native spinners etc are derived from this -->
        <item name="android:colorAccent">@color/primaryColor</item>

        <!-- AppSwitcher and Statusbar backgrounds-->
        <item name="android:colorPrimary">@color/primaryColorDark</item>
        <item name="android:colorPrimaryDark">@color/primaryColorDark</item>

        <!-- the bottom nav-bar -->
        <item name="android:navigationBarColor">@color/primaryColorDark</item>

        <!-- date- and timepickers need their own themes -->
        <item name="android:datePickerDialogTheme">@style/MyPickerDialogTheme</item>
        <item name="android:timePickerDialogTheme">@style/MyPickerDialogTheme</item>
    </style>

    <style name="MyPickerDialogTheme" parent="android:Theme.Material.Light.Dialog">
        <item name="android:colorAccent">@color/primaryColor</item>
    </style>

    <!-- see https://stackoverflow.com/a/29014475 -->
</resources>

Please note we defined a basic theme using our primaryColor for almost anything and
we also defined another theme (inherited from android:Theme.Material.Light.Dialog)
for date and time pickers.
The most important variable to set is android:colorAccent as from this variable most other
color related variables are derived.

Step 2

Make sure our theme will be used for the app, therefore we prepare a hook-file
which manipulated the AndroidManifest.xml-file.
Give it a useful name, such as hooks/use.android.theme.js:

#!/usr/bin/env node
// see https://stackoverflow.com/a/35128023
module.exports = function(ctx) {
    var fs = ctx.requireCordovaModule('fs'),
        path = ctx.requireCordovaModule('path'),
        xml = ctx.requireCordovaModule('cordova-common').xmlHelpers;

    var manifestPath = path.join(ctx.opts.projectRoot, 'platforms/android/app/src/main/AndroidManifest.xml');
    var doc = xml.parseElementtreeSync(manifestPath);
    if (doc.getroot().tag !== 'manifest') {
        throw new Error(manifestPath + ' has incorrect root node name (expected "manifest")');
    }

    //adds the tools namespace to the root node
    doc.getroot().attrib['xmlns:tools'] = 'http://schemas.android.com/tools';
    //add tools:replace in the application node
    doc.getroot().find('./application').attrib["android:theme"] = "@style/doneoTheme";
    doc.getroot().find('./application/activity').attrib["android:theme"] = "@style/doneoTheme";

    //write the manifest file
    fs.writeFileSync(manifestPath, doc.write({indent: 4}), 'utf-8');

};

Step 3

Let Cordova do the work, add the following to config.xml:

   <platform name="android">
        ...
        <resource-file src="path/to/styles.xml" target="app/src/main/res/values/styles.xml" />
        <hook src="hooks/use.android.theme.js" type="before_compile" />
    </platform>

The first command copies the styles.xml where our App can find it later.
The second command runs the hook to manipulate AndroidManifest.xml.

Step 4

To use our new theme with the datepickers provided by Cordoava-plugin-datepicker
we need to explicitly set the androidTheme-option to 0 to tell the date-picker-plugin
to use the Android theme used by MainActivity!

    constructor(
        public datePicker: DatePicker,
    ){}

    public showPicker(){
        let options = {
            ...
            androidTheme: 0, //we need to set to 0, to use theme of MainActivity
            ...
        }
        this.datePicker.show(options)
            .then( (value: Date) => {
                ...			
            })
            .catch ((err) => {
				...
            });
    }

See here for details
on why we have to use 0:

If themeResId is 0, the dialog will be inflated using the theme specified by the android:timePickerDialogTheme attribute on the parent context's theme

@mrphuzz
Copy link

mrphuzz commented Apr 18, 2018

Hi there. Is this post regarding custom colors verified to work? If so, I can't figure it out on my end. I'm using a Galaxy S8. I'm using Cordova CLI. I installed the plugin, and it works. Default, it shows up dark. I can change androidTheme: window.datePicker.ANDROID_THEMES.THEME_DEVICE_DEFAULT_LIGHT and it goes light. So at a basic level, the plugin works. But I can't get any changes as described in this post to work. It's probably me. So I will describe my environment.

In step 1, I changed primaryColor to #ff0000, named the file styles.xml, and chose to save it to the project root hooks folder.

In step 2, I named it use.android.theme.js and placed it in the project root hooks folder.

In step 3, I added those two middle lines into the config.xml <platform name="android"> section that is at the root of the Cordova project. I also changed the path to hooks/styles.xml.

In step 4, in my javascript, I added/changed androidTheme: 0.

What I EXPECT is that the theme would be light and the accent color would be red. But it isn't. It's the dark theme, and the accent color is whatever the default dark theme is.

What am I doing wrong? Thanks!

@abood91
Copy link

abood91 commented Apr 18, 2018

same problem here i fallowed the tutorial above but no changes accept that it turn to dark theme
@mrphuzz have you figured out the solution ? (my hooks and themes folder is in resources/android/hooks or resources/android/theme)

@abood91
Copy link

abood91 commented Apr 18, 2018

@znegva Could you please provide us with complete code example, i have tried your steps but nothing actually changes on the app. your help will be appreciated since i have to finish this project asap

@znegva
Copy link

znegva commented Apr 18, 2018

Difficult to diagnose from here, but please check if

  • the styles.xml had been copied to platforms/android/app/src/main/res/values/styles.xml and
  • if your platforms/android/app/src/main/AndroidManifest.xml had been edited correctly, the application-node and its <activity android:name="MainActivity">-node should have android:theme="@style/doneoTheme" applied.

If thats not the case, then something in step 3 gone wrong...

Also please note, that these steps are tested to work with cordova-android 7.0.0 (and probably above).
In prior versions the file-structure is somewhat different and you have to adopt the location of the AndroidManifest.xml and probably the location of additional resource-files such as styles.xml.

@mrphuzz
Copy link

mrphuzz commented Apr 18, 2018 via email

@abood91
Copy link

abood91 commented Apr 19, 2018

@znegva I am using phonegap to build the app, i cannot verify the AndroidManifest.xml file but i can verify that styels.xml was copied to the correct folder, thanks for the reply and looking forward for more instruction / help
ok i have verified that my AndroidManifest.xml has the theme on it

<application android:hardwareAccelerated="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/doneoTheme">
        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@style/doneoTheme" android:windowSoftInputMode="adjustResize">
            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
......

-cheers

@mrphuzz
Copy link

mrphuzz commented Apr 20, 2018 via email

@abood91
Copy link

abood91 commented Apr 20, 2018

hello @mrphuzz
i believe also the issue relies in the hooks file as its not being applied from my examination,

there could be 2 problems

  1. if you are using phonegap cloud to build the application then cordova hooks cannot work as i think they are not supported

  2. it might be that this line is trying to access AndroidManifest from the wrong path (for me that is still an issue ) but looking at your file structure it should be alright
    var manifestPath = path.join(ctx.opts.projectRoot,'platforms/android/app/src/main/AndroidManifest.xml'); in my case should be
    var manifestPath = path.join(ctx.opts.projectRoot,'platforms/android/AndroidManifest.xml');

I am also using Cordova 8.0.0 like your case

@mrphuzz
Copy link

mrphuzz commented Apr 20, 2018 via email

@abood91
Copy link

abood91 commented Apr 22, 2018

Hello @mrphuzz am not quite sure about the specification of android manifest but if you fallowed the steps described by @znegva, and if the theme does not apply as you said and that you have ti manually specify the theme. this means that the problem is in the hooks file. am facing the same issue and i believe that the hooks is not being applied. in your case all the steps above should be correct. GL

@abood91
Copy link

abood91 commented Apr 22, 2018

Here i will describe what should you do to get custom themes to apply if you are using Phonegap (cloud) to build your app.

Step1:

Fallow @znegva step 1 Generate your custom styles.xml:

<resources>
    <color name="primaryColor">#0277BD</color>
    <color name="primaryColorDark">#004C8C</color>
    <style name="doneoTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar">
        <!-- on startup the background and app-name is shown, we use the same color to see just background.. -->
        <item name="android:textColorPrimary">@color/primaryColorDark</item>
        <item name="android:colorBackground">@color/primaryColorDark</item>

        <!-- native spinners etc are derived from this -->
        <item name="android:colorAccent">@color/primaryColor</item>

        <!-- AppSwitcher and Statusbar backgrounds-->
        <item name="android:colorPrimary">@color/primaryColorDark</item>
        <item name="android:colorPrimaryDark">@color/primaryColorDark</item>

        <!-- the bottom nav-bar -->
        <item name="android:navigationBarColor">@color/primaryColorDark</item>

        <!-- date- and timepickers need their own themes -->
        <item name="android:datePickerDialogTheme">@style/MyPickerDialogTheme</item>
        <item name="android:timePickerDialogTheme">@style/MyPickerDialogTheme</item>
    </style>

    <style name="MyPickerDialogTheme" parent="android:Theme.Material.Light.Dialog">
        <item name="android:colorAccent">@color/primaryColor</item>
    </style>

    <!-- see https://stackoverflow.com/a/29014475 -->
</resources>

Please note we defined a basic theme using our primaryColor for almost anything and
we also defined another theme (inherited from android:Theme.Material.Light.Dialog)
for date and time pickers.
The most important variable to set is android:colorAccent as from this variable most other
color related variables are derived.

In my case i have modified couple of other variables fallowing this post the first theme as it applies for dialogs

Step2:

Let Cordova do the work, add the following line to config.xml:

<platform name="android">
         .....
        <resource-file src="path/to/styles.xml" target="app/src/main/res/values/styles.xml" />
</platform>

Step3:

To use our new theme with the datepickers provided by Cordoava-plugin-datepicker
we need to explicitly set the androidTheme option to 0 to tell the date-picker-plugin
to use the Android theme used by MainActivity!

 constructor(
        public datePicker: DatePicker,
    ){}

    public showPicker(){
        let options = {
            ...
            androidTheme: 0, //we need to set to 0, to use theme of MainActivity
            ...
        }
        this.datePicker.show(options)
            .then( (value: Date) => {
                ...			
            })
            .catch ((err) => {
				...
            });
    }

See here for details
on why we have to use 0:

Step4:

Download apktool and SignApk

Fallow the installation process of apktool (i have used the latest apktool_2.3.2.jar ) and SignApk. Here is a good tutorial that describes the fallowing steps in details.

After compiling and building the apk using Phonegap download the .apk file to your local disk and place it in the same folder where you copied the apktool files navigate using terminal or cmd to that location and execute the command:
apktool d YourApkName.apk.
That will generate a folder with the same apk name, navigate to that folder and edit the Androidmanifest.xml file so that in your <activity tag change the default theme to android:theme="@style/doneoTheme" or whatever name you named it in step 1. it would be good to verify that color.xml and styles.xml files under res/values folder contain your custom theme and custom colors.

once you have saved your changes execute:
apktool b YourApkFolderName.
Navigate to that folder ApkFolderName\dist and copy the apk file from there to the location where you extracted SignApk to.

With terminal`cmdnavigate to that location and execute this command: java -jar signapk.jar certificate.pem key.pk8 YourApkName.apk YourDesiredApkName.apk Finally you are ready to copy theYourDesiredApkName.apk` to your device and test

-cheers

@ArinaWik
Copy link

ArinaWik commented Aug 8, 2018

Hey, I want to change the datePicker color also. I have tried all the steps described in the tutorial.
I have checked and in AndroidManifest.xml the doneoTheme is applied. Here is the code:

application android:hardwareAccelerated="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/doneoTheme"

However when I run ionic cordova run android I am getting the following error:

**C:\platforms\android\build\intermediates\manifests\full\debug\AndroidManifest.xml:45: error: Error: No resource found that matches the given name (at 'theme' with value '@style/doneoTheme').
FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':processDebugResources'.

com.android.ide.common.process.ProcessException: Failed to execute aapt**

my config.xml :

Do you have any idea what is wrong?

Thanks beforehand.

@brudevit
Copy link

brudevit commented Aug 8, 2018 via email

@andrews3
Copy link

Worked here, cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants