Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-17998] Android 5.0: In a two column picker the selection indicator does not match the postion of the selected item

GitHub Issuen/a
TypeBug
PriorityLow
StatusClosed
ResolutionFixed
Resolution Date2016-02-23T17:48:17.000+0000
Affected Version/sRelease 3.4.1, Release 3.5.0
Fix Version/sRelease 5.2.1
ComponentsAndroid
Labelsqe-3.4.1, qe-3.5.0
ReporterEwan Harris
AssigneeAshraf Abu
Created2014-11-10T23:04:52.000+0000
Updated2016-03-03T18:22:29.000+0000

Description

Description

On an Android L device when using a two column picker the selection indicator and the selected item do not line up and the selected item appears lower than the indicator. This only happens on a Android L device, on a 4.4.2 device the two match up correctly.

Steps To Reproduce

1. Add the attached app.js to a project. 2. Build to

Actual Result

The application matches screenshot AndroidLPicker

Expected Result

The application should match screenshot 442Picker

Attachments

FileDateSize
442Picker.png2014-11-10T23:04:52.000+000093643
Android 4.4.4.png2016-01-19T17:53:58.000+000069919
Android 6.0.png2016-01-19T17:54:00.000+000047034
AndroidLPicker.png2014-11-10T23:04:52.000+000086559
app.js2014-11-10T23:04:52.000+0000886

Comments

  1. Hieu Pham 2014-11-13

    master PR: https://github.com/appcelerator/titanium_mobile/pull/6340
  2. Lokesh Choudhary 2014-12-08

    This issue is reproducible with latest 3.5.0 SDK. Environment: Appc Studio : 3.4.1.201410281743 Ti SDK : 3.5.0.v20141208092926 CLI : 3.4.1 Alloy : 1.5.1 GA Code Processor : 1.1.1 MAC Yosemite : 10.10 Nexus 5 - Android 5.0 Nexus 9 - Android 5.0.1
  3. Mark Mokryn 2015-01-20

  4. jay splaine 2015-01-20

    Is this related or shall I open a new ticket? The column heights DO match when format24 = false (no am/pm column). 3.5.0.GA Lolipop preview emulator !http://i.imgur.com/wJJNlj3.png! Ti.UI.backgroundColor = 'white'; var win = Ti.UI.createWindow({ exitOnClose : true, layout : 'vertical' }); var picker = Ti.UI.createPicker({ font: { fontWeight : 'bold', fontSize : 45 }, type : Ti.UI.PICKER_TYPE_TIME, format24 : false, top : 150, left : 75, width : Ti.UI.FILL, useSpinner : true, }); win.add(picker); win.open();
  5. Mark Mokryn 2015-01-20

    As I wrote, in 3.6.0 we will be using Appcompat to generate the picker, so the underlying Android implementation will change. So you should check these issues on 3.6.0 with this PR: https://github.com/appcelerator/titanium_mobile/pull/6552 - which will be accepted at some point.
  6. jay splaine 2015-01-20

    Thanks. Note, the reason why we use 'useSpinner' is because minuteInterval doesn't work without it. Will the AppCompat picker support minuteInterval?
  7. Mark Mokryn 2015-01-20

    The API is not changing, just the internal Android implementation.
  8. jay splaine 2015-10-19

  9. Ingo Muschenetz 2015-10-22

    Marking for 5.3.0 since it is already in a Sprint.
  10. Ashraf Abu 2015-12-03

    PR https://github.com/appcelerator/titanium_mobile/pull/7525 was merged.
  11. Lokesh Choudhary 2016-01-19

    I see the following while verifying the fix: 1. On Android 6.0 the selection indicator is not exactly in the center for some selected items(You can this by changing the setSelectedRow property in the code). Also, the height of the picker for column1 changes with different setSelectedRow selections. 2. On android 4.4.4 this is not the case, the indicator is in the center of the selected item. Attached screenshot for reference(Android 6.0.png & android 4.4.4.png).
        Ti.UI.backgroundColor = 'white';
        var win = Ti.UI.createWindow({
          exitOnClose: true,
          layout: 'vertical'
        });
         
        var picker = Ti.UI.createPicker({
          top:50,
          useSpinner: true
        });
        picker.selectionIndicator = true;
         
        var fruit = [ 'Bananas', 'Strawberries', 'Mangos', 'Grapes' ];
        var color = [ 'red', 'green', 'blue', 'orange' ];
         
        var column1 = Ti.UI.createPickerColumn();
         
        for(var i=0, ilen=fruit.length; i<ilen; i++){
          var row = Ti.UI.createPickerRow({
            title: fruit[i]
          });
          column1.addRow(row);
        }
         
        var column2 = Ti.UI.createPickerColumn();
         
        for(var i=0, ilen=color.length; i<ilen; i++){
          var row = Ti.UI.createPickerRow({ title: color[i] });
          column2.addRow(row);
        }
         
        picker.add([column1,column2]);
         
        win.add(picker);
         
        win.open();
         
        // must be after picker has been displayed
        picker.setSelectedRow(0, 1, false); // select Mangos
        picker.setSelectedRow(1, 2, false); // select Orange
        
    Reopening. Environment: Appc Studio : 4.5.0.201601131150 Ti SDK : 5.2.0.v20160114021251 Ti CLI : 5.0.5 Alloy : 1.7.26 MAC Yosemite : 10.10.5 Appc NPM : 4.2.2 Appc CLI : 5.1.0 Node: v0.12.27 Nexus 6P - Android 6.0 Genymotion emulator: Android 4.4.4, Android 6.0
  12. Chee Kiat Ng 2016-01-26

    let's deprecate this for 5.2.0. If possible, come up with the native implementation. If not, we can have it for 6.0.0 and remove this. Even better if we can implement this in hyper loop.
  13. Ashraf Abu 2016-02-03

    So if it is agreed, I'll deprecate this. For Android instead, you'll want to do:
        Ti.UI.backgroundColor = 'white';
        var win = Ti.UI.createWindow({
        exitOnClose: true,
        layout: 'vertical'
        });
        
        var picker = Ti.UI.createPicker({
        top:50
        });
        picker.selectionIndicator = true;
        
        var pickertwo = Ti.UI.createPicker({
        top:70
        });
        
        pickertwo.selectionIndicator = true;
        
        var fruit = [ 'Bananas', 'Strawberries', 'Mangos', 'Grapes' ];
        var color = [ 'red', 'green', 'blue', 'orange' ];
        
        var column1 = Ti.UI.createPickerColumn();
        
        for(var i=0, ilen=fruit.length; i<ilen; i++){
        var row = Ti.UI.createPickerRow({
        title: fruit[i]
        });
        column1.addRow(row);
        }
        
        var column2 = Ti.UI.createPickerColumn();
        
        for(var i=0, ilen=color.length; i<ilen; i++){
        var row = Ti.UI.createPickerRow({ title: color[i] });
        column2.addRow(row);
        }
        
        picker.add(column1);
        pickertwo.add(column2);
        
        win.add(picker);
        win.add(pickertwo);
        
        win.open();
        
        // must be after picker has been displayed
        picker.setSelectedRow(0, 1, false); // select Mangos
        pickertwo.setSelectedRow(0, 2, false); // select Orange
        
    This would also imply Multi-Column Picker would not be available as it is now using the Android's spinner API ([http://developer.android.com/guide/topics/ui/controls/spinner.html])
  14. Chee Kiat Ng 2016-02-03

    agreed
  15. Ashraf Abu 2016-02-03

    This is marked for 5.2.1, hence for Master branch: PR https://github.com/appcelerator/titanium_mobile/pull/7673
  16. Ashraf Abu 2016-02-23

    5_2_X (5.2.1) PR https://github.com/appcelerator/titanium_mobile/pull/7768
  17. jay splaine 2016-02-23

    [~cng] [~msamah] [~mokesmokes] As a cloud services customer and long-time paid appcelerator account holder (OnForce.com), removing this feature breaks the functionality of being able to set an interval (like 15 minutes) on a time picker, which we rely on. Before removing the useSpinner option, can we get a native implementation working first? This way, there's no gap in functionality / regression for us...
  18. Ashraf Abu 2016-02-23

    [~jsplaine] This is not removed. This is deprecated. And thanks for leaving a comment. This still works as it is. Time picker still works. Nothing has changed for time picker.
  19. Ashraf Abu 2016-02-23

    Do let me know if there's something I misunderstood.
  20. jay splaine 2016-02-23

    [~msamah] You got it. And thanks for responding so quickly. I'm just pushing for a fix honestly :). We've been kicking this can down the road for a long time. Even before this ticket was opened (which was October 2014). There's a bit of Appcelerator/OnForce history that revolves around the useSpinner option. The history: When I was hired a little over 2 years ago, at OnForce, Appcelerator was creating custom builds with a useSpiner patch for us and had been for some months previous to my hire. Unfortunately, whenever we needed to upgrade to a new SDK, we'd also have to go through long rounds of back-and-forth to get a new patched build. Always an arduous process. The bug with the picker is that it was tiny. Very difficult to interact with. The term "tiny picker" is well known in my office. Eventually, it was fixed for a GA release. But then 5.0 happened and created the cosmetic issue covered by this ticket (which QA at OnForce loves to complain about). You can see above where [~mokesmokes] asserts that this will be fixed in 3.6.0. We just want a date picker that supports minute intervals.
  21. Ashraf Abu 2016-02-23

    [~jsplaine] Have you tried this time picker? This is what I believe should be used instead of the spinner. This is what Android natively uses.
        // this sets the background color of the master UIView (when there are no windows/tab groups on it)
        Titanium.UI.setBackgroundColor('#000');
         
        // create tab group
        var tabGroup = Titanium.UI.createTabGroup();
         
         
        //
        // create base UI tab and root window
        //
        var win1 = Titanium.UI.createWindow({  
            title:'Tab 1',
            backgroundColor:'#fff'
        });
        var tab1 = Titanium.UI.createTab({  
            icon:'KS_nav_views.png',
            title:'Tab 1',
            window:win1
        });
         
        var button1 = Titanium.UI.createButton({
        	color:'#999',
        	title:'Open time picker',
        	font:{fontSize:20,fontFamily:'Helvetica Neue'},
        	textAlign:'center',
        	width:'auto'
        });
         
        win1.add(button1);
         
        button1.addEventListener('click', function() {
        	var picker = Ti.UI.createPicker( {
        	    type : Ti.UI.PICKER_TYPE_TIME
        	});
        	 
        	picker.showTimePickerDialog({
        	    callback: function(e) {
        	        if (e.cancel) {
        	            Ti.API.info('user canceled dialog');
        	        } else {
        	            Ti.API.info('user selected date: ' + e.value);
        	        }
        	    }
        	});
        });
         
         
         
         
        //
        // create controls tab and root window
        //
        var win2 = Titanium.UI.createWindow({  
            title:'Tab 2',
            backgroundColor:'#fff'
        });
        var tab2 = Titanium.UI.createTab({  
            icon:'KS_nav_ui.png',
            title:'Tab 2',
            window:win2
        });
         
        var label2 = Titanium.UI.createLabel({
        	color:'#999',
        	text:'I am Window 2',
        	font:{fontSize:20,fontFamily:'Helvetica Neue'},
        	textAlign:'center',
        	width:'auto'
        });
         
         
         
        var button2 = Titanium.UI.createButton({
        	color:'#999',
        	title:'Open date picker',
        	font:{fontSize:20,fontFamily:'Helvetica Neue'},
        	textAlign:'center',
        	width:'auto'
        });
         
        win2.add(button2);
         
        button2.addEventListener('click', function() {
        	var picker = Ti.UI.createPicker( {
        	    type : Ti.UI.PICKER_TYPE_DATE
        	});
        	 
        	picker.showDatePickerDialog({
        	    callback: function(e) {
        	        if (e.cancel) {
        	            Ti.API.info('user canceled dialog');
        	        } else {
        	            Ti.API.info('user selected date: ' + e.value);
        	        }
        	    }
        	});
        });
         
         
        //
        //  add tabs
        //
        tabGroup.addTab(tab1);  
        tabGroup.addTab(tab2);  
         
         
        // open tab group
        tabGroup.open();
        
  22. jay splaine 2016-02-23

    [~msamah] Can you show me an example of it working when a minute interval is set? Say, 15 minutes? We don't care about the look and feel of useSpinner. The issue all these years is that the minuteInterval parameter does not work with Picker on android, unless useSpinner is set to true. The docs show now that minuteInterval is iOS only: http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Picker
  23. Ashraf Abu 2016-02-23

    [~jsplaine] I understand what you mean now. That feature is not available in Android (for now). That can possibly be a new feature request for Android's time picker in Titanium SDK. The code that I mentioned, makes use of [http://developer.android.com/guide/topics/ui/controls/pickers.html]. They do not come with interval parameter.
  24. jay splaine 2016-02-23

    Thanks [~msamah], But this feature already exists on android. We've been using it for ~3 years. With useSpinner. It's just looks bad now as of android 5.0 (which this ticket addresses). We've been requesting that the broken feature be fixed, again for years now. For quite a while, Appcelerator was creating custom builds with the feature fixed for us. It was broken as it was too small to use. Then the fix/patch was integrated in.. 3.2.? maybe? Then it broke (cosmetically) in android 5.0. At the end of the day, we still don't have a nice looking picker, with minuteInterval, even after years of discussions not unlike like this one. Can we just fix useSpinner and be done with it?
  25. Ashraf Abu 2016-02-23

    [~jsplaine] I think I understand how you are using this now. For now the fix for this ticket at least is just the deprecation and the underlying implementation needs to be revisited and investigated to solve for your use case (the usage of minuteInterval). Created a ticket to handle this. TIMOB-20441 The spinner in useSpinner is being deprecated so that we can use Android's TimePicker. This should prevent issues with how the UI (cosmetic) part is. Thus, it seems that the thing that would prevent you from using the TimePicker is the ability to set the minuteInterval. This would be a feature that would need to be implemented in Android's TimePicker. (TIMOB-20441) Would this address your need?
  26. jay splaine 2016-02-23

    [~msamah], I can't really say that it addresses it and we're certainly not happy about it. What this "solution" is ... well it's yet another postponement after so many other postponements. It's been years of this very same conversation really. What is the timeline for this being implemented?
  27. Ashraf Abu 2016-02-24

    [~jsplaine] I'll try to resolve this issue that would be acceptable for you.
  28. Lokesh Choudhary 2016-03-01

    Verified the fix. The {noFormat}useSpinner{noFormat} property is deprecated & the native android picker is used. Also, multi column picker can't be used as of now with the native picker( from above comments). The date & time picker are the android native ones. Closing. Environment: Appc Studio : 4.5.0.201602170831 Ti SDK : 5.2.1.v20160228190750 Ti CLI : 5.0.6 Alloy : 1.7.33 MAC El Capitan : 10.11.13 Appc NPM : 4.2.3 Appc CLI : 5.2.0 Node: 4.2.2 Nexus 6P - Android 6.0.1
  29. Ashraf Abu 2016-03-02

    Although this is closed as fixed. We should look into this.

JSON Source