[TIMOB-13914] Android: 'longpress' event is not working in ListView
| GitHub Issue | n/a |
|---|---|
| Type | Bug |
| Priority | High |
| Status | Closed |
| Resolution | Fixed |
| Resolution Date | 2014-11-25T07:56:48.000+0000 |
| Affected Version/s | Release 3.1.0 |
| Fix Version/s | 2013 Sprint 15 API, 2013 Sprint 15, Release 3.4.2, Release 3.5.0 |
| Components | Android |
| Labels | listview, qe-closed-3.1.2, qe-testadded |
| Reporter | Meenakshi Pathak |
| Assignee | Hieu Pham |
| Created | 2013-05-20T12:44:09.000+0000 |
| Updated | 2014-11-25T07:56:48.000+0000 |
Description
'longpress' event is not working in listView. Here is the test case:
var win = Ti.UI.createWindow({backgroundColor: 'white'});
var plainTemplate = {
childTemplates: [
{
type: 'Ti.UI.Label', // Use a label
bindId: 'rowtitle', // Bind ID for this label
properties: { // Sets the Label.left property
left: '10dp'
}
},
{
type: 'Ti.UI.ImageView', // Use an image view
bindId: 'pic', // Bind ID for this image view
properties: { // Sets the ImageView.image property
image: 'KS_nav_ui.png'
}
},
{
type: 'Ti.UI.Button', // Use a button
bindId: 'button', // Bind ID for this button
properties: { // Sets several button properties
width: '80dp',
height: '30dp',
right: '10dp',
title: 'press me'
}
}
]
};
function report(e) {
Ti.API.info(e.type);
}
var listView = Ti.UI.createListView({
// Maps the plainTemplate object to the 'plain' style name
templates: { 'plain': plainTemplate },
// Use the plain template, that is, the plainTemplate object defined earlier
// for all data list items in this list view
defaultItemTemplate: 'plain'
});
var data = [];
for (var i = 0; i < 3; i++) {
data.push({
// Maps to the rowtitle component in the template
// Sets the text property of the Label component
rowtitle : { text: 'Row ' + (i + 1) },
// Sets the regular list data properties
properties : {
itemId: 'row' + (i + 1),
accessoryType: Ti.UI.LIST_ACCESSORY_TYPE_NONE
}
});
}
listView.addEventListener('longpress', function(e){
alert("longpress fired!!!");
});
win.add(listView);
win.open();
Additional test case:
Testing steps: 1. Run above code 2. Long press the list item, you should see "Long press" in log.var win = Ti.UI.createWindow({backgroundColor: 'white'}); var plainTemplate = { childTemplates: [ { type: 'Ti.UI.Label', // Use a label bindId: 'rowtitle', // Bind ID for this label properties: { // Sets the Label.left property left: '10dp', backgroundColor: 'blue' } }, { type: 'Ti.UI.ImageView', // Use an image view bindId: 'pic', // Bind ID for this image view properties: { // Sets the ImageView.image property image: 'KS_nav_ui.png' } }, { type: 'Ti.UI.Button', // Use a button bindId: 'button', // Bind ID for this button properties: { // Sets several button properties width: '80dp', height: '30dp', right: '10dp', title: 'press me' } } ], events: { longpress: function(e) { Ti.API.log("Long press"); } } }; function report(e) { Ti.API.info(e.type); } var listView = Ti.UI.createListView({ // Maps the plainTemplate object to the 'plain' style name templates: { 'plain': plainTemplate }, // Use the plain template, that is, the plainTemplate object defined earlier // for all data list items in this list view defaultItemTemplate: 'plain' }); var data = []; for (var i = 0; i < 3; i++) { data.push({ // Maps to the rowtitle component in the template // Sets the text property of the Label component rowtitle : { text: 'Row ' + (i + 1) }, // Sets the regular list data properties properties : { itemId: 'row' + (i + 1), accessoryType: Ti.UI.LIST_ACCESSORY_TYPE_NONE } }); } var section = Ti.UI.createListSection(); section.setItems(data); listView.appendSection(section); win.add(listView); win.open();master PR: https://github.com/appcelerator/titanium_mobile/pull/4497
An extended test case:
*Note:* When longpressing the label or the right white space of each item, it will log "LISTVIEW LONGPRESS" on iOS; but it does not log on Android. This parity issue is filed in TIMOB-14679.var win = Ti.UI.createWindow({backgroundColor: 'white'}); function isValidVar(check){ if (check !== undefined && check !== null){ return true; } return false; } function clickHandler(e){ var message = 'Section title:'+e.section.headerTitle+'\nsectionIndex:'+e.sectionIndex+'\nitemIndex:'+e.itemIndex; if(isValidVar(e.bindId)){ message += '\nbindId:'+e.bindId; } if(isValidVar(e.itemId)){ message += '\nitemId:'+e.itemId; } Ti.API.info(message); } // Create a custom template that displays an image on the left, // then a title next to it with a subtitle below it. var myTemplate = { childTemplates: [ { // Image justified left type: 'Ti.UI.ImageView', // Use an image view for the image bindId: 'pic', // Maps to a custom pic property of the item data events:{ longpress:clickHandler }, properties: { // Sets the image view properties width: '50dp', height: '50dp', left: 0 } }, { // Title type: 'Ti.UI.Label', // Use a label for the title bindId: 'info', // Maps to a custom info property of the item data properties: { // Sets the label properties color: 'black', font: { fontFamily:'Arial', fontSize: '20dp', fontWeight:'bold' }, left: '60dp', top: 0, } }, { // Subtitle type: 'Ti.UI.Label', // Use a label for the subtitle bindId: 'es_info', // Maps to a custom es_info property of the item data properties: { // Sets the label properties color: 'gray', font: { fontFamily:'Arial', fontSize: '14dp' }, left: '60dp', top: '25dp', } } ] }; var listView = Ti.UI.createListView({ // Maps myTemplate dictionary to 'template' string templates: { 'template': myTemplate }, // Use 'template', that is, the myTemplate dict created earlier // for all items as long as the template property is not defined for an item. defaultItemTemplate: 'template' }); var sections = []; var fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits / Frutas'}); var fruitDataSet = [ // the text property of info maps to the text property of the title label // the text property of es_info maps to text property of the subtitle label // the image property of pic maps to the image property of the image view { info: {text: 'Apple'}, es_info: {text: 'Manzana'}, pic: {image: 'face_happy.png'}}, { info: {text: 'Banana'}, es_info: {text: 'Banana'}, pic: {image: 'KS_nav_ui.png'}} ]; fruitSection.setItems(fruitDataSet); sections.push(fruitSection); var vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables / Verduras'}); var vegDataSet = [ { info: {text: 'Carrot'}, es_info: {text: 'Zanahoria'}, pic: {image: 'KS_nav_views.png'}}, { info: {text: 'Potato'}, es_info: {text: 'Patata'}, pic: {image: 'face_happy.png'}} ]; vegSection.setItems(vegDataSet); sections.push(vegSection); var grainSection = Ti.UI.createListSection({ headerTitle: 'Grains / Granos'}); var grainDataSet = [ { info: {text: 'Corn'}, es_info: {text: 'Maiz'}, pic: {image: 'KS_nav_ui.png'}}, { info: {text: 'Rice'}, es_info: {text: 'Arroz'}, pic: {image: 'KS_nav_views.png'}} ]; grainSection.setItems(grainDataSet); sections.push(grainSection); listView.setSections(sections); win.add(listView); listView.addEventListener('longpress', function(e){ Ti.API.info('LISTVIEW LONGPRESS '+JSON.stringify(e)); }) win.open();backport PR: https://github.com/appcelerator/titanium_mobile/pull/4504
Tested above "Additional test case" and verified correct behavior with: Appcelerator Studio, build: 3.1.2.201308021524 Titanium SDK, build: 3.1.2.v20130806104555 Alloy 1.2.0-alpha6 CLI: 3.1.2-alpha Devices: Nexus7(2) Android version 4.3 GalaxyS3 Android version 4.0.4 Confirmed "Long press" in log.
Titanium SDk, buld: 3.1.2.GA Actual result:
08-16 15:10:52.710: I/TiAPI(5209): LISTVIEW LONGPRESS {"type":"longpress","source":The longpress event still not triggered on Android using SDK 3.2.1 GA. The event is triggered normally in iOS. The longclick event in Android is also not triggered.
This event doesn't trigger while running in Android 4.2.2. Development done with Alloy on SDK 3.2.1 GA. To be specific event doesn't trigger when a row within the ListView is clicked. When clicked on a non-row area in the view it does get triggered. Alloy XML:
Controller item binding:<ListView id="lvMyList" onLongpress="lvMyList_onLongPress"> <ListSection id="lsMyList"></ListSection> </ListView>This bug should be reopened.var myListData = []; if(otherData && otherData.length > 0){ otherData.forEach(function(item){ myListData.push({ properties: { title: item.otherName } }); }); } $.lsMyList.items = myListData;More details on this issue. Event remembers previous click on individual item. For example if item at index 1 was clicked before longpress on non-item area it fires event with itemIndex 1. If non-item area is longpressed without clicking any item first it fires event with itemIndex 0.
Reopened according to comments. Confirmed with Appcelerator Studio, build: 3.2.1.201402061120 Node.JS Version: v0.10.13 NPM Version: 1.3.2 ├── acs@1.0.12 ├── alloy@1.3.1 ├── npm@1.3.2 ├── titanium@3.2.1 └── titanium-code-processor@1.1.0
Anyone looking for a workaround should use a custom item template and place longpress event on the view within the custom template. Event fires correctly with the above steps.
Replicated same error with Nexus 5, SDK 3.2.1 and following code:
Works fine if I longpress outside the rows, but doesn't fire if I longpress one of them.var win = Ti.UI.createWindow({backgroundColor: 'white'}); var listView = Ti.UI.createListView(); var sections = []; var section = Ti.UI.createListSection(); var data = [ { properties: { title: 'Row 1'} }, { properties: { title: 'Row 2'} } ]; section.setItems(data); sections.push(section); listView.setSections(sections); win.add(listView); listView.addEventListener('longpress', function(e){ Ti.API.info('LISTVIEW LONGPRESS '+JSON.stringify(e)); }); win.open();Working as expected with: Appc-Studio: 3.4.1.201410281743 Titanium SDK: 3.5.0.v20141124155715 Titanium CLI: 3.4.1 GA Alloy : 1.5.1 GA OS: Mac OSX 10.9.4 Xcode: 6.1 Device: Samsung Galaxy Tab 3 (4.4.2)