[TIMOB-27530] Android: UI glitches out when using 'applyProperties' with Scroll View Touch Listeners
| GitHub Issue | n/a |
|---|---|
| Type | Bug |
| Priority | Medium |
| Status | Closed |
| Resolution | Fixed |
| Resolution Date | 2020-03-12T02:03:01.000+0000 |
| Affected Version/s | Release 8.2.0, Release 8.3.0 |
| Fix Version/s | Release 9.0.1 |
| Components | Android |
| Labels | engSchedule |
| Reporter | Samir Mohammed |
| Assignee | Yordan Banev |
| Created | 2019-11-06T16:21:27.000+0000 |
| Updated | 2020-06-05T10:28:32.000+0000 |
Description
Application UI glitches out when trying to drag a label horizontally.
*Test case:*
var win = Ti.UI.createWindow({
backgroundColor: '#fff'
});
var scroll = Ti.UI.createScrollView({
scrollType: 'vertical',
contentHeight: 3010,
text: 'Scroll View'
});
var width = 150, height = 90;
for (var i = 0; i < 30; i++) {
scroll.add(Ti.UI.createLabel({
draggable: true,
text: 'Drag Me Horizontally ' + (i + 1), textAlign: 'center',
color: '#000',
top: i * 100 + 10,
width: width, height: height,
backgroundColor: '#eee'
}));
}
scroll.addEventListener('touchstart', doDrag);
scroll.addEventListener('touchmove', doDrag);
scroll.addEventListener('touchcancel', doDrag);
scroll.addEventListener('touchend', doDrag);
function doDrag(evt) {
Ti.API.info('Event Fired On: ' + evt.source.text);
if (evt.source.draggable) {
var global = evt.source.convertPointToView({ x: evt.x, y: evt.y }, scroll);
evt.source.applyProperties({
left: global.x - width / 2
});
}
}
win.add(scroll);
win.open();
*Test Steps*
PR: https://github.com/appcelerator/titanium_mobile/pull/11327
FR Passed. PR Merged.
*Closing ticket*, fix verified in SDK version
9.0.0.v20200103081513. Test and other information can be found at: https://github.com/appcelerator/titanium_mobile/pull/11327Reopening ticket as label flys of the screen when tapping on a label. *Test Environment*
[~smohammed], First, I would say this ticket's sample code is written wrong. The touch listeners are set up on the
ScrollView, not theLabelviews. The issue is thedoDrag()function is moving the ScrollView instead of the labels. And the event bubbling feature walks up the parent hierarchy, not the children. I can see that this code does what you expect on iOS, but I would argue that iOS is the one that's doing it wrong. Second, there is a separate bug here. The problem is the point returned by theconvertPointToView()method is wrong. It looks like it's returning the result in pixels instead of dips (aka: dp). I wrote this up as a separate ticket [TIMOB-27807].The below code works on both Android and iOS. I've implemented a work-around on Android where it takes the returned
convertPointToView()coordinates and converts them from pixels to dp. Android also has a nasty habit of sliding the view just to the left of your finger. We can look into that when addressing [TIMOB-27807] in the future.var win = Ti.UI.createWindow({ backgroundColor: '#fff' }); var scroll = Ti.UI.createScrollView({ scrollType: 'vertical', contentHeight: 3010, text: 'Scroll View' }); var width = 150, height = 90; for (var i = 0; i < 30; i++) { var label = Ti.UI.createLabel({ draggable: true, text: 'Drag Me Horizontally ' + (i + 1), textAlign: 'center', color: '#000', top: i * 100 + 10, width: width, height: height, backgroundColor: '#eee' }); label.addEventListener('touchstart', doDrag); label.addEventListener('touchmove', doDrag); label.addEventListener('touchcancel', doDrag); label.addEventListener('touchend', doDrag); scroll.add(label); } function doDrag(evt) { Ti.API.info('Event Fired On: ' + evt.source.text); if (evt.source.draggable) { var point = evt.source.convertPointToView({ x: evt.x, y: evt.y }, scroll); if (Ti.Android) { point.x = Ti.UI.convertUnits(point.x + 'px', 'dip'); point.y = Ti.UI.convertUnits(point.y + 'px', 'dip'); } evt.source.left = undefined; evt.source.center = { x: point.x }; switch (evt.type) { case 'touchstart': scroll.scrollingEnabled = false; break; case 'touchcancel': case 'touchend': scroll.scrollingEnabled = true; break; } evt.cancelBubble = true; } } win.add(scroll); win.open();