Yes
If both longPress and tap event are bound to a ListView, it's difficult handling both events without losing some feature.
Android (not tested on iOS yet)
Plugin(s):
"nativescript-cardview": "^1.2.0",
"nativescript-dom": "^1.0.7",
"nativescript-floatingactionbutton": "^2.2.5",
"nativescript-geolocation": "0.0.13",
"nativescript-google-maps-sdk": "^1.3.14",
"nativescript-material-icons": "^1.0.1",
"nativescript-ng2-fonticon": "^1.2.6",
"nativescript-phone": "^1.2.2",
"nativescript-snackbar": "^1.1.4",
"nativescript-social-share": "^1.3.1",
"nativescript-sqlite": "^1.1.2",
"nativescript-telerik-ui": "^1.4.1",
"nativescript-theme-core": "^0.1.3",
"tns-platform-declarations": "^2.3.0"
I will report my tests to explain in detail the problem:
CASE 1: itemTap and longPress events on ListView
<ListView id="contactsList" [items]='contacts' (itemTap)="onItemTap($event)" (longPress)="onItemPress($event)">
<template let-contact='item'>
<GridLayout columns="80, *">
<Image col="0" [src]="contact.icon" stretch="aspectFill" verticalAlignment="center" horizontalAlignment="center" class="contact-icon"></Image>
<StackLayout col="1" verticalAlignment="center" horizontalAlignment="left" color="black" margin="5 0">
<Label [text]="contact.name" verticalAlignment="center" horizontalAlignment="left" textWrap="true" id="personalContactName" class="h2"></Label>
<Label [text]="contact.phone" verticalAlignment="center" horizontalAlignment="left" class="h3"></Label>
<Label [text]="contact.notes" verticalAlignment="center" horizontalAlignment="left" textWrap="true" class="h3 font-italic"></Label>
</StackLayout>
</GridLayout>
</template>
</ListView>
CASE 2: tap and longPress events on ListView
<ListView id="contactsList" [items]='contacts' (tap)="onItemTap($event)" (longPress)="onItemPress($event)">
<template let-contact='item'>
<GridLayout columns="80, *">
<Image col="0" [src]="contact.icon" stretch="aspectFill" verticalAlignment="center" horizontalAlignment="center" class="contact-icon"></Image>
<StackLayout col="1" verticalAlignment="center" horizontalAlignment="left" color="black" margin="5 0">
<Label [text]="contact.name" verticalAlignment="center" horizontalAlignment="left" textWrap="true" id="personalContactName" class="h2"></Label>
<Label [text]="contact.phone" verticalAlignment="center" horizontalAlignment="left" class="h3"></Label>
<Label [text]="contact.notes" verticalAlignment="center" horizontalAlignment="left" textWrap="true" class="h3 font-italic"></Label>
</StackLayout>
</GridLayout>
</template>
</ListView>
CASE 3: tap and longPress events on GridLayout
<ListView id="contactsList" [items]='contacts' >
<template let-contact='item'>
<GridLayout columns="80, *" (tap)="onTap(contact)" (longPress)="onLongPress(contact)">
<Image col="0" [src]="contact.icon" stretch="aspectFill" verticalAlignment="center" horizontalAlignment="center" class="contact-icon"></Image>
<StackLayout col="1" verticalAlignment="center" horizontalAlignment="left" color="black" margin="5 0">
<Label [text]="contact.name" verticalAlignment="center" horizontalAlignment="left" textWrap="true" id="personalContactName" class="h2"></Label>
<Label [text]="contact.phone" verticalAlignment="center" horizontalAlignment="left" class="h3"></Label>
<Label [text]="contact.notes" verticalAlignment="center" horizontalAlignment="left" textWrap="true" class="h3 font-italic"></Label>
</StackLayout>
</GridLayout>
</template>
</ListView>
CASE 4: loaded event on ListView
I've also tried to attach events using the _loaded_ event and putting the following code in my component:
contactsListLoaded(args) {
var listView = args.object as ListView;
listView.on("itemTap, longPress", (args) => {
console.log("Event: " + args.eventName + ", sender: " + args.object);
});
}
In this case, also changing the attached events similarly to previous cases, I experience same issues described above.
NOTE
I tried to access the long pressed item by using _args.object.bindingContext_ (as explained in another closed issue) but that property always return _undefined_.
How can I get tap/itemTap and longPress events work correctly, access index of tapped/longPressed item and keep the ripple effect active?
Thank you very much!
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
I'll chime in here; I've noticed the same thing, but I can fill in one thing on iOS; longPress will not trigger a tap, where the tap event is still fired on Android as bm-software stated. Please note, if you add the "touch" even on iOS; it messes up both the other events. On Android all three can works together.
Hello @bm-software
Indeed _LongPress_ gesture will trigger _itemTap_ for the NativeScript list-view on gesture end.
We will investigate that behavior further. Meanwhile, it is expected taht Tap and LongPress will not return the index of your list-view item. The list view has its own gesture _itemTap_ with _ItemEventData_ which returns the item index.
However, in angular you can create your own index for the item template and pass it to the gestures you are using for your inner component.
e.g.
list.component.html
<ListView [items]="countries" class="list-group">
<template let-country="item" let-myIndex="index">
<GridLayout class="list-group-item" [id]="myIndex" (tap)="onTap($event)" (longPress)="onLongPress($event)">
<Label [text]="country.name"></Label>
</GridLayout>
</template>
</ListView>
list.component.ts
public onTap(args: EventData) {
console.log(args.object);
console.log("onTap id: " + args.object.get("id"));
}
public onLongPress(args: EventData) {
console.log(args.object);
console.log("onLongPress id: " + args.object.get("id"));
}
Still, this won't resolve the missing ripple effect - as a workaround, you can create your own ripple with native code and attach it to the clickable components in your template.
@NickIliev Thank you for your exaustive answer.
A solution may not be adding an _itemHold_ event like Telerik UI RadListView?
I'm trying using it and events works fine but also in RadListView the ripple effect doesn't work :(
Hi,
Some times longPress event automatically calling tap functionality..
for example I want to show some dialog data with 'close' button onLongPress.
When I longPress it showing Dialog but page is redirected i.e calling the (tap) functionality.
I want to prevent the tap on longPress any one can help me how to handle this?
<StackLayout class="list-group-item" (longPress)="onLongPressKid($event, item)" (tap)="redirectToKidDashboard(item)">
</StackLayout>
Any chance to get this fixed? Events are supposed to bubble, propagating up through the "DOM" (I'm not sure how they are supposed to work in Nativescript, but the concept should be similar).
Yet if I listen for them they seem to stop propagating (that's why we loose the ripple effect).
Also I don't understand why putting an @HostListener directive inside a Label works, while using the very same directive against a custom component doesn't.
What's even more strange is that if I put my custom component inside a StackLayout and I apply my directive to it then it works once again.
Can you please explain me how Event propagation works in Nativescript and how I am supposed to solve this? Thanks
reproducible with modules 4.1
any update on this? I'm also experiencing this behaviour (only in iOS, Android works fine)
I also still have this issue on iOS. We currently fixed it by making our own tap/longpress handler by using the touch event. I explained it here: https://stackoverflow.com/a/60724213/999424
Most helpful comment
any update on this? I'm also experiencing this behaviour (only in iOS, Android works fine)