Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27530] Android: UI glitches out when using 'applyProperties' with Scroll View Touch Listeners

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2020-03-12T02:03:01.000+0000
Affected Version/sRelease 8.2.0, Release 8.3.0
Fix Version/sRelease 9.0.1
ComponentsAndroid
LabelsengSchedule
ReporterSamir Mohammed
AssigneeYordan Banev
Created2019-11-06T16:21:27.000+0000
Updated2020-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*

Create a Titanium application

Add the code above in to the ((app.js}}

Run on Android

Try to drag a label horizontally

*Actual result* Whole application moves and UI glitches out *Expected result* Only label should move horizontally

Comments

  1. Yordan Banev 2019-11-12

    PR: https://github.com/appcelerator/titanium_mobile/pull/11327
  2. Lokesh Choudhary 2019-12-13

    FR Passed. PR Merged.
  3. Samir Mohammed 2020-01-08

    *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/11327
  4. Samir Mohammed 2020-03-11

    Reopening ticket as label flys of the screen when tapping on a label. *Test Environment*
       MacOS Catalina: 10.15.1 beta
       Xcode: 11.3
       Java Version: 1.8.0_131
       Android NDK: 18.1.5063045
       Node.js: 10.16.3
       "NPM":"5.0.0-1","CLI":"8.0.0-master.10"
       Pixel xl (7.1.1) Emulator
       SDK Version: 9.0.0.v20200207114311
       
  5. Joshua Quick 2020-03-12

    [~smohammed], First, I would say this ticket's sample code is written wrong. The touch listeners are set up on the ScrollView, not the Label views. The issue is the doDrag() 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 the convertPointToView() 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].
  6. Joshua Quick 2020-03-12

    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();
       

JSON Source