Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-17357] Android: Support Material Theme

GitHub Issuen/a
TypeNew Feature
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2015-01-30T00:35:32.000+0000
Affected Version/sn/a
Fix Version/sRelease 4.0.0
ComponentsAndroid
Labelsandroid-l, module_materialtheme, qe-manualtest, qe-testadded
ReporterIngo Muschenetz
AssigneePing Wang
Created2014-07-22T16:22:47.000+0000
Updated2015-05-21T13:31:59.000+0000

Description

The material theme provides a new style for your app, system widgets that let you set their color palette, and default animations for touch feedback and activity transitions.

Attachments

FileDateSize
KSAfter.png2015-01-28T22:25:52.000+000083740
KSBefore.png2015-01-28T22:25:52.000+0000109930
MaterialDark.png2014-07-22T16:28:29.000+000088935
MaterialLight.png2014-07-22T16:28:29.000+000082081
timob17357.zip2014-11-11T19:00:42.000+0000639805

Comments

  1. Allen Yeung 2014-07-22

    As a part of this, we probably want to add support to customize the status/navigation bar. Depending on whether you can programmatically set certain values on the theme, there may need to be changes in the CLI.
  2. Ingo Muschenetz 2014-08-05

    This might "just work" as noted by http://stackoverflow.com/questions/24545394/how-to-use-actionbaractivity-with-theme-material.
  3. Ingo Muschenetz 2014-08-26

    This requires an update to the AppCompat library which is not at GA status yet. Thus, we will be merging this to the master branch (not 3.4.0). Once Android L is closer to release and the proper components are available, we can slot this in. My goal is this would appear on the 3.4.X branch as soon as is feasible, and likely ship with 3.4.1.
  4. Ingo Muschenetz 2014-11-07

    Confirmed, we can merge this into 3.4.2.
  5. Mark Mokryn 2014-11-08

  6. Ingo Muschenetz 2014-11-08

    I actually view these as separate. This is about allowing us to support the Material Guidelines (through the use of the new App Compat library). The second (TIMOB-17963) is about adopting changes throughout the SDK to bring us in line with updated practices.
  7. Mark Mokryn 2014-11-08

    Well, not sure where this issue belongs, but I looked into it and migrating tabs will be the main issue. The Toolbar is essentially a normal view so it doesn't allow putting tabs inside of it. Thus all the tab API in the action bar is deprecated. The action bar tabs will need to be migrated to PagerTabStrip or something similar (the tab content itself must be in a ViewPager as already in 3.5.0 and in this PR https://github.com/appcelerator/titanium_mobile/pull/6008 ). Moving to PagerTabStrip is not a huge task, but the action bar tabs had an advantage which is not available in Lollipop: in landscape mode the tabs moved into the action bar itself, and a lot of screen real estate was saved... There is no solution for this at the moment..... And indeed, if you check out the new Google Play app, for example, it only works in portrait mode on my S4.... If you do want this in 3.4.2 then I suggest merging https://github.com/appcelerator/titanium_mobile/pull/6008 (ready to merge for 3.5.0 and easy for 3.4.2, already did it in my 3_4_X fork), then we need to do the change I outlined above (use PagerTabStrip below the Toolbar) - and recommend no landscape mode on tabbed apps on phones - like the Google Play app.
  8. Mark Mokryn 2014-11-10

    In any case I suggest you create an API 21 branch off the current master, I think there are too many changes for this to go into 3.4.x Hopefully it can be merged back into master prior to 3.5.0.GA release
  9. Ping Wang 2014-11-11

    This ticket is fixed by this PR https://github.com/appcelerator/titanium_mobile/pull/6247. For FR, please run the attached project "timob17375" on 5.0 emulator/device. Should see the app title bar is blue, the textfield and the cursor are green.
  10. Mark Mokryn 2014-11-11

    [~pwang] since we're using appcompat shouldn't this work on all Android versions supported by Titanium, not just Android 5.0?
  11. Ping Wang 2014-11-11

    It should be. But when we run the attached app on a Android 4.x device, the textfield and the cursor are black *not* green. The same behavior for a native Android app. Seems although appcompat library supports material theme on all Android versions, the behaviors are not exactly the same on different Android versions.
  12. Mark Mokryn 2014-11-12

    So if possible it would be good to see an example of how to style such elements for all Android versions, though I assume that over time appcompat will take care of it.
  13. Mark Mokryn 2014-11-12

    [~pwang] I found an explanation regarding the non-tinted widgets on pre-Lollipop versions. See https://chris.banes.me/2014/10/17/appcompat-v21/ , the FAQ at the bottom: {quote} Why is my EditText (or other widget listed above) not being tinted correctly on my pre-Lollipop device? The widget tinting in appcompat works by intercepting any layout inflation and inserting a special tint-aware version of the widget in its place. For most people this will work fine but I can think of a few scenarios where this won’t work including: You have your own custom version of the widget (i.e. you’ve extended EditText) You are creating the EditText without a LayoutInflater (i.e. calling new EditText()). You are hooking up to the LayoutInflater’s Factory. The special tint aware widgets are currently hidden because they’re an unfinished implementation detail. {quote} So it appears that this stuff will have to wait until Google finishes the implementation. So this can't go into a GA release since (apparently) there is no way for us to style some elements at the moment with API21. For example checkboxes in a test app were barely visible with this SDK.
  14. Mark Mokryn 2014-11-12

    Also tried this with a test app using tabs on an API 21 emulator. Looked OK when in portrait mode. When the emulator was rotated to landscape the tab indicator was gone. Again, the ActionBar navigation APIs, tabs, etc are deprecated. So please accept the PR I noted above, and then we need to switch all the ActionBar tab APIs to something like what was done in the Google IO app: https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/SlidingTabLayout.java
  15. Mark Mokryn 2014-11-13

    Why is this resolved when it's not really usable on pre-L devices and issues with tabs?
  16. Mark Mokryn 2014-11-14

    Please provide guidance on how to style a dark themed app. I added a checkbox and picker to the attached app with the following results, and made the window background black (Theme.AppCompat is dark, should handle it fine). The app built with current 3.5.0 is not usable on a KitKat device - note the checkbox and text field are not visible, nor is the text in the picker: [Android 5.0 emulator built with 3.5.0](http://imgur.com/cTGYFp2) [KitKat device built with 3.5.0](http://imgur.com/JXnJDvK) [KitKat device built with 3.4.2](http://imgur.com/56HoWTY) Here is the app:
        var win = Ti.UI.createWindow({
            backgroundColor:'black',
            title: 'Material Theme'
        });
         
        var textField = Ti.UI.createTextField({
          top: '400dp',
          width: 200,
          color: "white"
        });
        var checkbox = Ti.UI.createSwitch({title: 'checkbox', top: '50dp', color: 'white', style: Titanium.UI.Android.SWITCH_STYLE_CHECKBOX});
        win.add(checkbox);
        win.add(textField);
        var picker = Ti.UI.createPicker({
          top:'100dp'
        });
        
        var data = [];
        data[0]=Ti.UI.createPickerRow({title:'Bananas'});
        data[1]=Ti.UI.createPickerRow({title:'Strawberries'});
        data[2]=Ti.UI.createPickerRow({title:'Mangos'});
        data[3]=Ti.UI.createPickerRow({title:'Grapes'});
        
        picker.add(data);
        picker.selectionIndicator = true;
        
        win.add(picker);
        win.open();
        
    To run the app with 3.4.2 I created a default Titanium app, replaced the content of app.js with the above code, and added the following to tiapp.xml:
            <android xmlns:android="http://schemas.android.com/apk/res/android">
                <manifest>
                    <application android:theme="@style/Theme.AppCompat"/>
                </manifest>
            </android>
        
  17. Ingo Muschenetz 2014-11-14

    We are somewhat caught between a rock and a hard place. If we want to provide Material support, we need the AppCompat library, however, there are the issues you have raised. FWIW, 3.4.2 is not going out immediately, so we are hoping Google will provide an update. Otherwise, we will need to look for workarounds. In the meantime, [a discussion](https://m.google.com/app/basic/stream/z12wytojryatwley304cj3pqryaugdnpuwc0k?cbp=xwaw2t2feuqr&partnerid=operamini1104&sview=27&cid=5&soc-app=115&soc-platform=1&aa=ac&spath=/app/basic/%2BWojtekKalicinski/posts&sparm=cbp%3D8qbn6wbnd2l0%26partnerid%3Doperamini1104%26sview%3D27%26cid%3D5%26soc-app%3D115%26soc-platform%3D1%26spath%3D/app/basic/%252BMaurycyDamianWasilewski/posts%26sparm%3Dcbp%253Dvh4nl9q2zvpx%2526partnerid%253Doperamini1104%2526sview%253D27%2526cid%253D5%2526soc-app%253D115%2526soc-platform%253D1%2526spath%253D/app/basic/%25252BMaurycyDamianWasilewski/posts%2526sparm%253Dcbp%25253Daixcgybw4w6n%252526partnerid%25253Doperamini1104%252526sview%25253D20%252526cid%25253D5%252526soc-app%25253D115%252526soc-platform%25253D1%252526spath%25253D/app/basic/photos/%2525252BMaurycyDamianWasilewski/album/5944211647300246225/5944211644056603618%252526sparm%25253Dcbp%2525253D1c8jonqdp0vz7%25252526partnerid%2525253Doperamini1104%25252526sview%2525253D28#comment) I found around this topic.
  18. Mark Mokryn 2014-11-14

    [~ingo] I doubt those kinds of workarounds will work on all the widgets..... As a Titanium app developer I would prefer the 3_4_X branch is kept "production worthy" as close as possible, and major breaking stuff like this should be in a development branch. I'm frankly surprised it was pushed to master, and I certainly hope it doesn't go into 3_4_X until it's rock solid. The UI is so broken on pre-L devices, it will make even basic testing difficult, and I doubt that is in anyone's interest. I honestly think that merge should be reverted, and this should go into a development branch for now, not master. We also don't know when Google will fill in the missing pieces, since as Chris Banes wrote, it works for people who inflate the widgets from XML, and that's the vast majority of native apps. So one way to attack this can be to do just that in Titanium.... Not extend the widget classes, and define them in XML layouts. Is this possible/realistic? The list of widgets is not huge.... It's also not just the widget tinting: as I wrote earlier, all Action Bar navigation modes are deprecated, and if you search on Stack Overflow you will see developers reporting crashes when using Action Bar tabs. I didn't experience a crash in the 5 minutes I tried it, but I saw right away that tab styling is broken too.
  19. Ingo Muschenetz 2014-11-14

    [~mokesmokes] Please note that master *is* our development branch. It is debatable if we should revert the merge for 3.4.X. We will discuss.
  20. Mark Mokryn 2014-11-14

    I understand it is your development branch, but traditionally it is kept quite clean from breaking stuff. The general perception is fairly stable but not QA'ed to production. But this change is downright experimental at this point. Knowing it is so experimental, why would you even consider pushing it to two branches? Just so we're on the same page: I'm all for the Material theme, and if it works it makes styling and branding lots easier, and we should definitely push it! But only if it works :)
  21. Ping Wang 2014-11-14

    {quote} ... since as Chris Banes wrote, it works for people who inflate the widgets from XML, ... {quote} I doubt it works for inflating the widgets from XML. I ran a native Android app to test several different widgets using appcompat lib and the "@style/Theme.AppCompat" theme. I attached two screenshot for 5.0 emulator (nativeApp_5.0emulator.png) and 4.2.2 emulator (nativeApp_4.2.2emulator.png). And we can see it shows exactly the same issues in [~mokesmokes]'s Titanium test case. ************************************************************************************************** *Update:* My mistake. I did something wrong in my last test. Now I get the native Android app work fine on pre-Lollipop emulator. I deleted the two screenshots to avoid future confusion.
  22. Mark Mokryn 2014-11-15

    [~pwang] [~ingo] here's a quick test showing that inflated widgets are indeed tinted correctly on pre-L devices: https://github.com/appcelerator/titanium_mobile/pull/6356 Simple PR to inflate EditText. It was a quick hack so the text field won't autofocus when the window is shown, and won't fire the postlayout event (since I deleted the TiEditText class), but other than that it seems to work fine. Here's a screen shot from my S4 running 4.4.2 http://imgur.com/ZWd4u20
  23. Mark Mokryn 2014-11-15

    It was actually a no brainer to add the checkbox, switch, and spinner to the PR so I added them. Updated image from a KitKat device: http://imgur.com/ucJir9J Notes: 1. You may wish to add the postlayout event back (I suppose use addOnLayoutChangeListener for each of these) 2. I didn't bother to add code to autofocus the EditText So barring these issues it's basically done :) I still think it's key to make sure all of Titanium looks good for both light and dark themes. Plus it's still not ready for prime time since the deprecated ActionBar APIs are used (Tabs). Thus I urge you guys to finally accept https://github.com/appcelerator/titanium_mobile/pull/6008 , and then remove all the deprecated Tab, NavigationMode APIs and integrate the SlidingTabsLayout from the Google I/O app, and use Toolbar. None of the Javascript APIs should change. Update: the Switch titleOff and titleOn properties should be removed from the Javascript API. I got it to show, but it shows up in tiny font inside the switch handle, not even close to being readable. So basically with the SwitchCompat we have a switch very similar to iOS - no text :) (PR updated accordingly) Also checked changing the parent theme to Theme.AppCompat.Light.DarkActionBar, setting Window backgroundColor to white, checkbox and textfield color param to black. Looks good on both KitKat and Lollipop. http://imgur.com/1qoDuxJ
  24. Martin Guillon 2014-11-26

    To bring my 2 cents on this matter, this was enough for me. Everything now works with custom classes http://stackoverflow.com/questions/26670234/material-design-for-subclass-of-edittext
  25. Mark Mokryn 2014-11-26

    :) But this is using internal classes.... could break at any time, especially since Google said the implementation is incomplete. Do all the relevant classes have such internal implementations? Got a link to their source code?
  26. Martin Guillon 2014-11-26

    Yes but those classes should become visible in the future. Yes it is a quick fix, but it will work as long as you don't update appcompat, so good with me!
  27. Mark Mokryn 2014-12-04

    Heads up: We will get crashes on Samsung 4.2.2 devices if ProGuard configuration is incorrect, see https://code.google.com/p/android/issues/detail?id=78377
  28. Ingo Muschenetz 2014-12-05

    [~mokesmokes] thanks for the note.
  29. Ashraf Abu 2015-01-07

    As mentioned by [~farfromrefuge], using the internal classes eg. https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/internal/widget/TintEditText.java does make it work. Just need to extend TintEditText instead of EditText for TiEditText. [~mokesmokes] : And it does seem that all the relevant classes have such an internal implementation: https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/internal/widget (all the Tint versions) This could possibly work. Would this be a good idea? Note: If this way is used, probably need to check on this classes when the AppCompat is updated too.
  30. Ashraf Abu 2015-01-07

    It seems that the way it is being "injected" is through here: At line 751 https://android.googlesource.com/platform/frameworks/support/+/master/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
  31. Mark Mokryn 2015-01-07

    My preference would be to create the widgets in a standard manner, thus simplifying support and upgrading down the road. The only real issue with this PR https://github.com/appcelerator/titanium_mobile/pull/6356 is that for [~pwang] there were some issues with the keyboard showing up or not - while in my case the keyboard showed up just fine on the same test apps. I think we should investigate this and try to close in standard fashion - at this point I don't see why we can't just use XML layouts where necessary. Let's also not forget that there are two more related issues that need to be tackled: 1. ActionBar tabs (and all other ActionBar navigation modes) are deprecated in API21. I can confirm I saw TabGroup issues with this support library. The solution is to change the TabGroup code to use Google's Sliding Tabs samples, or perhaps integrate this library: https://github.com/neokree/MaterialTabs 2. Use Toolbar instead of ActionBar in the SDK, which opens up a lot of design options (Toolbar is easily customized and can behave as a normal view, unlike ActionBar).
  32. Ping Wang 2015-01-07

    I agree with Mark that creating widgets from XML is a better way, except for EditText. Here is the issue I concerned: TIMOB-4755. I tested TIMOB-4755 on 4.0 and 4.4.4 device. If we don't override the method onCheckIsTextEditor(), we still can see the soft keyboard appear and disappear in a flash.
  33. Mark Mokryn 2015-01-07

    [~pwang] I believe this issue may be addressed by using EditText.setInputType() [http://developer.android.com/reference/android/widget/TextView.html#setInputType(int)] There are various Q&A's on this as well: http://stackoverflow.com/questions/5803193/android-disable-soft-keyboard-at-all-edittexts http://stackoverflow.com/questions/10636635/disable-keyboard-on-edittext etc
  34. Ping Wang 2015-01-08

    PR: https://github.com/appcelerator/titanium_mobile/pull/6552 For FR: 1. Please run the test case below with a material theme. Should see tint on the text field, checkbox and switch. All the widgets and the "postlayout" event should work fine.
        --------------------------- /platform/android/res/values/custom_theme.xml ---------------------------
        <?xml version="1.0" encoding="utf-8"?>
        <resources>
        <style name="materialTheme" parent="@style/Theme.AppCompat">
            <item name="colorPrimary">#0000FF</item>
            <item name="colorPrimaryDark">#FF0000</item>
            <item name="colorAccent">#00FF00</item>
        </style>
        </resources>
        
        --------------------------- app.js ---------------------------
        var win = Ti.UI.createWindow({
            backgroundColor:'black',
            title: 'Material Theme',
            theme: "materialTheme",
            layout: "vertical"
        });
         
        var textField = Ti.UI.createTextField({
          width: 200,
          color: "white"
        });
        
        var checkbox = Ti.UI.createSwitch({title: 'checkbox', color: 'white', style: Titanium.UI.Android.SWITCH_STYLE_CHECKBOX});
        
        var s = Ti.UI.createSwitch({
        	style: Titanium.UI.Android.SWITCH_STYLE_TOGGLEBUTTON,
        	titleOn:'Enabled',
          	titleOff:'Disabled'
        });
        
        var s_old = Ti.UI.createSwitch({
        	style: Titanium.UI.Android.SWITCH_STYLE_TOGGLEBUTTON_OLD,
        	titleOn:'Enabled',
          	titleOff:'Disabled'
        });
        
        var picker = Ti.UI.createPicker();
         
        var data = [];
        data[0]=Ti.UI.createPickerRow({title:'Bananas'});
        data[1]=Ti.UI.createPickerRow({title:'Strawberries'});
        data[2]=Ti.UI.createPickerRow({title:'Mangos'});
        data[3]=Ti.UI.createPickerRow({title:'Grapes'});
         
        picker.add(data);
        picker.selectionIndicator = true;
         
        textField.addEventListener("postlayout", function(e){
        	Ti.API.info("*************** postlayout: text field");
        });
        
        checkbox.addEventListener("postlayout", function(e){
        	Ti.API.info("*************** postlayout: checkbox");
        });
        
        s.addEventListener("postlayout", function(e){
        	Ti.API.info("*************** postlayout: switch");
        });
        
        s_old.addEventListener("postlayout", function(e){
        	Ti.API.info("*************** postlayout: toggle button");
        });
        
        picker.addEventListener("postlayout", function(e){
        	Ti.API.info("*************** postlayout: picker");
        });
        
        win.add(textField);
        win.add(checkbox);
        win.add(s);
        win.add(s_old);
        win.add(picker);
        win.open();
        
    2. Please run KS to make sure nothing is broken.
  35. Mark Mokryn 2015-01-29

    A note regarding the KS screenshots: Current Android design guidelines specify that tabs must be all text or all icons but not both: [tab design guidelines](http://www.google.com/design/spec/components/tabs.html#tabs-content) : "Do not combine text labels with icons. Use either all text labels or all icon labels." Additionally, as I wrote earlier ActionBar tabs are deprecated in API21, and tabs will not work well on older APIs either with this AppCompat version - I have seen all kinds of issues (such as in the attached After image). We need to migrate to something like [MaterialTabs](https://github.com/neokree/MaterialTabs) or [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip)
  36. Hieu Pham 2015-01-29

  37. Ping Wang 2015-01-30

    Thanks Mark. Already created two tickets related to the tab (TIMOB-18356) and Toolbar (TIMOB-18357) but forgot to link them. Now they are linked.
  38. Hieu Pham 2015-02-04

    Mark, after some digging, I think that the UI difference is theme related. The before image is using Holo theme, while after is using Material theme. So I don't think this is a bug. Can you elaborate on the other issues you've seen using the latest Appcompat libraries regarding tabs? Thanks,
  39. Mark Mokryn 2015-02-05

    Yes, it is theme-related. But as all the ActionBar navigation modes are deprecated this particular AppCompat version will apparently not style them properly. It's been a while since I last tried it, but I recall issues when rotating the device to landscape mode - IIRC in that case the tab indicator went completely AWOL. I also think there are issues depending upon the device API level, e.g. there are folks reporting that their tabs [don't appear](http://www.reddit.com/r/androiddev/comments/2jmuec/material_design_tabs) at all with this AppCompat version:
  40. Lokesh Choudhary 2015-03-19

    Verified the implementation. New properties related to material theme seem to work as expected. Closing. Environment: Appc Studio : 3.5.1.201412091616 Ti SDK : 4.0.0.v20150317234215 CLI : 4.0.0-alpha Alloy : 1.6.0-alpha MAC Yosemite : 10.10.2 Nexus 5 - Android 5.1

JSON Source