Forum Xamarin.Forms

It's possible to add Tap gesture to the Entry?

tkowalczyktkowalczyk PLMember, University ✭✭
edited July 2014 in Xamarin.Forms

Hi All,
As I wrote in the title, it's possible to add Tap gesture to the Entry?
This code works for Label but doesn't work for Entry:

var tapEntryRecognizer = new TapGestureRecognizer(); tapFocusEntryRecognizer.Tapped += async (s, e) => { Console.WriteLine("tapped"); }; tapEntry.GestureRecognizers.Add(tapFocusEntryRecognizer);

Posts

  • tkowalczyktkowalczyk PLMember, University ✭✭

    I found out that we can use Focused event which will be the same in most cases:

    tapEntry.Focused += async (s, e) => { Console.WriteLine("tapped"); };

  • Hi Tomasz, your solution is working first time, second time focused event is not firing , we need to tap on out side of Entry. Is there any solution for this.

  • tkowalczyktkowalczyk PLMember, University ✭✭

    Hi @RaviKumarKumar‌ I didn't noticed such error. Maybe try to implement custom gesture, simple workaround can be found here: https://github.com/tkowalczyk/SimpleCustomGesturesForms

  • voidvoid DKBeta ✭✭✭
    edited October 2014

    As of 1.2.3 this works on iOS but not on android, field being an Entry

    field.GestureRecognizers.Add(new TapGestureRecognizer
    {

        Command = new Command(async () => 
        { 
    
                await parentPage.Navigation.PushAsync (... ));
    
        }),
    
        NumberOfTapsRequired = 1,
    

    });

    The event/command is never fired.

  • 15mgm1515mgm15 USMember ✭✭✭✭

    @tkowalczyk Did you succeeded adding a gesture recognizer to the entry?

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    You can use MR.Gestures to handle the Tapped and other gesture events on an Entry.
    Download the free GestureSample sourcecode from GitHub and run it on your device. There is a sample for Entry (located within "Views").

  • RonaldKasperRonaldKasper ATMember ✭✭

    If you set IsEnabled to false, the TappedGestureRecognizer works all the time. This could be used for cases where you only show data and open a search-dialog in the Tapped Event for example.

  • DennisMelansonDennisMelanson USMember

    @RonaldKasper I see this working fine in iOS, but not android. Have you gotten this to work?

  • HunumanHunuman GBMember ✭✭✭✭
    edited April 2016

    A possible work around would be to put the Entry in a layout and add the Tap gesture to the layout.
    A Frame may be the best for this.

    Hope this helps,
    Tim

    PS. If the result looks wrong, remember Frames have a default Padding of 20.

  • RonaldKasperRonaldKasper ATMember ✭✭

    I finally did it this way and used an editable Entry because the "Focused" event doesn't fire on disabled Entries. After firing, I immediately remove the focus from the control to make it possible to press again (otherwise the focus stays at the Entry and an additional tap doesn't do anything)

    var txtProject = new Entry ();
    txtProject.Focused+= async (sender, e) => {
    
        //remove the focus so that the next Tap-Event raises again after tapping.
        Device.BeginInvokeOnMainThread(()=>{
         txtProject.Unfocus();
        });
        await Navigation.PushAsync(new MyChooseProjectPage());
    }
    
  • tribaltribal USMember ✭✭✭

    I wanted a box to show up only when the Editor was clicked. Based on @RonaldKasper's idea above I enclosed the Editor inside a ContentView and set the IsEnabled to false. I then added a TapGestureRecognizer Command on the ContentView & that works perfectly all the time

  • MarceloAmadorMarceloAmador USMember ✭✭

    I tried to use a Frame but still not working when I tap the Entry. I put GestureRecognizers inside Frame and inside Entry but nothing triggers when I tap the Entry. The Frame GestureRecognizer triggers only when I tap in all other places except on the Entry.

    <ListView x:Name="countsheetItemsByLocation" IsGroupingEnabled="True" GroupDisplayBinding="{Binding InventoryGroupName}" ItemTapped="countsheetListView_ItemTapped" CachingStrategy="RecycleElement" > <ListView.GroupHeaderTemplate> <DataTemplate> <ViewCell> <ViewCell.View> <Grid BackgroundColor="#EAEAEA" > <Label Text="{Binding InventoryGroupName}" Style="{StaticResource labelGroupTitleStyle}" Margin="10,0,0,0" /> </Grid> </ViewCell.View> </ViewCell> </DataTemplate> </ListView.GroupHeaderTemplate> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Frame Padding="0,0,0,0"> <Frame.GestureRecognizers> <TapGestureRecognizer x:Name="frameLocationTapGesture" NumberOfTapsRequired="1" Tapped="frameLocationTapGesture_Tapped"/> </Frame.GestureRecognizers> <StackLayout HeightRequest="80" BackgroundColor="{Binding SelectedItemBackgroundColor}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="60*" /> <ColumnDefinition Width="15*" /> <ColumnDefinition Width="15*" /> <ColumnDefinition Width="10*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Label Grid.Column="0" Grid.Row="0" Text="{Binding ItemName}" Style="{StaticResource labelStyle}" VerticalOptions="Start" Margin="10,0,0,0"/> <Label Grid.Column="0" Grid.Row="1" Text="{Binding CaseSizeDescription}" TextColor="Black" FontSize="12" VerticalOptions="End" Margin="10,0,0,0"/> <CustomRenderers:MyEntry Grid.Column="1" Grid.RowSpan="2" x:Name="txtCountByLocation" Text="{Binding CaseCount}" TextColor="Black" FontSize="14" HorizontalTextAlignment="End" Keyboard="Numeric" IsEnabled="{Binding Selected}" NeedToFocus="{Binding Selected}" Focused="txtCountByLocation_Focused" Unfocused="txtCountByLocation_Unfocused"> <CustomRenderers:MyEntry.GestureRecognizers> <TapGestureRecognizer x:Name="txtCountByLocationTapGesture" NumberOfTapsRequired="1" Tapped="txtCountByLocationTapGesture_Tapped"/> </CustomRenderers:MyEntry.GestureRecognizers> </CustomRenderers:MyEntry> <Label Grid.Column="2" Grid.RowSpan="2" Text="{Binding RecipeUom}" Style="{StaticResource labelStyle}" TextColor="Black" FontSize="14"/> <Image Grid.Column="3" Grid.RowSpan="2" Source="ic_info.png" HorizontalOptions="End" x:Name="imgSelectCountsheet" IsVisible="{Binding Selected}" Margin="0,0,10,0"> <Image.GestureRecognizers> <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="TapGestureRecognizer_Tapped_1"/> </Image.GestureRecognizers> </Image> </Grid> </StackLayout> </Frame> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>

  • MarceloAmadorMarceloAmador USMember ✭✭

    Put the inside the StackLayout and also don't work when tap the Entry

  • MOFADevsMOFADevs QAUniversity ✭✭

    @RonaldKasper

    var txtProject = new Entry ();
    txtProject.Focused+= async (sender, e) => {

    //remove the focus so that the next Tap-Event raises again after tapping.
    Device.BeginInvokeOnMainThread(()=>{
     txtProject.Unfocus();
    });
    await Navigation.PushAsync(new MyChooseProjectPage());
    

    }

    The above does work on both Android and iOS! Thanks

  • SreeeeSreeee INMember ✭✭✭✭✭

    @15mgm15 said:
    @tkowalczyk Did you succeeded adding a gesture recognizer to the entry?

    I tried Gesture Recognizer, but no effect.

    My code:

            <Entry
                        TextColor="Black"
                        x:Name="phone">
                    <Entry.GestureRecognizers>
                        <TapGestureRecognizer
                            Tapped="StartCall"
                            NumberOfTapsRequired="1">
                        </TapGestureRecognizer>
                    </Entry.GestureRecognizers> 
                </Entry>
    
    void StartCall(object sender,EventArgs args)
            {
                DisplayAlert("Alert","Hi","ok");
            }
    

    No alert showing on ui when tapping on entry...

  • seanydaseanyda GBMember ✭✭✭✭✭

    @Sreeee said:

    @15mgm15 said:
    @tkowalczyk Did you succeeded adding a gesture recognizer to the entry?

    I tried Gesture Recognizer, but no effect.

    My code:

            <Entry
                        TextColor="Black"
                        x:Name="phone">
                    <Entry.GestureRecognizers>
                        <TapGestureRecognizer
                            Tapped="StartCall"
                            NumberOfTapsRequired="1">
                        </TapGestureRecognizer>
                    </Entry.GestureRecognizers> 
                </Entry>
    

    void StartCall(object sender,EventArgs args)
    {
    DisplayAlert("Alert","Hi","ok");
    }

    No alert showing on ui when tapping on entry...

    Change it to this -

    async void StartCall(object sender,EventArgs args)
            {
                await DisplayAlert("Alert","Hi","ok");
            }
    

    Did that help?

  • SreeeeSreeee INMember ✭✭✭✭✭

    @seanyda said:

    @Sreeee said:

    @15mgm15 said:
    @tkowalczyk Did you succeeded adding a gesture recognizer to the entry?

    I tried Gesture Recognizer, but no effect.

    My code:

            <Entry
                        TextColor="Black"
                        x:Name="phone">
                    <Entry.GestureRecognizers>
                        <TapGestureRecognizer
                            Tapped="StartCall"
                            NumberOfTapsRequired="1">
                        </TapGestureRecognizer>
                    </Entry.GestureRecognizers> 
                </Entry>
    
    void StartCall(object sender,EventArgs args)
            {
                DisplayAlert("Alert","Hi","ok");
            }
    

    No alert showing on ui when tapping on entry...

    Change it to this -

    async void StartCall(object sender,EventArgs args)
            {
                await DisplayAlert("Alert","Hi","ok");
            }
    

    Did that help?

    No :)

  • 15mgm1515mgm15 USMember ✭✭✭✭

    You can try Mr Gestures:

    http://www.mrgestures.com/

  • SreeeeSreeee INMember ✭✭✭✭✭

    @Sreeee said:

    @15mgm15 said:
    @tkowalczyk Did you succeeded adding a gesture recognizer to the entry?

    I tried Gesture Recognizer, but no effect.

    My code:

            <Entry
                        TextColor="Black"
                        x:Name="phone">
                    <Entry.GestureRecognizers>
                        <TapGestureRecognizer
                            Tapped="StartCall"
                            NumberOfTapsRequired="1">
                        </TapGestureRecognizer>
                    </Entry.GestureRecognizers> 
                </Entry>
    

    void StartCall(object sender,EventArgs args)
    {
    DisplayAlert("Alert","Hi","ok");
    }

    No alert showing on ui when tapping on entry...

    Updating the answer, this might help others :)

    I solved this issue by putting entry Inside StackLayout and give tap gesture to StackLayout

     <StackLayout>
            <Entry Placeholder="Phone number" TextColor="Black" x:Name="phone"/>
           <StackLayout.GestureRecognizers>
              <TapGestureRecognizer
            Tapped="StartCall"
            NumberOfTapsRequired="1">
            </TapGestureRecognizer>
            </StackLayout.GestureRecognizers>
      </StackLayout>
    
  • deczalothdeczaloth DEMember ✭✭✭

    @Sreeee said:
    I solved this issue by putting entry Inside StackLayout and give tap gesture to StackLayout



    <StackLayout.GestureRecognizers>


    </StackLayout.GestureRecognizers>

    Does this actually work for Android on your side? This is not working for me...

  • SreeeeSreeee INMember ✭✭✭✭✭
    edited October 2018

    @deczaloth This is working fine in android, ios and UWP platforms. Adding the complete code with this comment.

    //Xaml codes
            <StackLayout>
                    <Entry
                        TextColor="Black"
                        x:Name="phoneone"/>
                        <StackLayout.GestureRecognizers>
                            <TapGestureRecognizer
                                    Tapped="CallingPhone1"
                                    NumberOfTapsRequired="1">
                            </TapGestureRecognizer>
                        </StackLayout.GestureRecognizers> 
                </StackLayout>
    
       //xaml.css codes
        public async void StartCall(object sender,EventArgs args)
                {
                      //My codes
                }
    

    If you have still problem, please share the code of yours :)

  • deczalothdeczaloth DEMember ✭✭✭

    Hi @Sreeee, thanks for your answer.

    Look, in a new Xamarin.Forms / Net Standard project i have

    MainPage.xaml

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:EntryTap"
                 x:Class="EntryTap.MainPage">
    
        <StackLayout>
            <!-- Place new controls here -->
            <Entry Placeholder="Tap here!"
                   TextColor="Black"
                   x:Name="phoneone"/>
    
            <StackLayout.GestureRecognizers>
                <TapGestureRecognizer Tapped="CallingPhone1"
                                      NumberOfTapsRequired="1"/>
            </StackLayout.GestureRecognizers>
        </StackLayout>
    
    </ContentPage>
    

    MainPage.xaml.cs

    using System;
    using Xamarin.Forms;
    
    namespace EntryTap
    {
        public partial class MainPage : ContentPage
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            public void CallingPhone1(object sender, EventArgs e)
            {
                // This is not reached
            }
        }
    }
    

    This is not working on my Samsung Galaxy Tab A with Android 7.0. Also tried on visual studio x86_phone emulator with Android 6.0 with the same results.

    Note: if i tap out of the Entry (the StackLayout occupies the whole Page) then the tap event is fired, but tapping ON THE ENTRY does not fire the tap event. Is this working on your side?

  • SreeeeSreeee INMember ✭✭✭✭✭

    @deczaloth It is working fine in my side.
    Give me some time, I will provide a sample project.

  • SreeeeSreeee INMember ✭✭✭✭✭

    @deczaloth Did you get a solution for this?

  • deczalothdeczaloth DEMember ✭✭✭
    edited October 2018

    @Sreeee said:
    @deczaloth Did you get a solution for this?

    Hi @Sreeee,

    Currently i am managing double taps on Entry via Custom Renderers. I am not able to make your method work: some how it is not working on my side. Even the super-simple project as i wrote above is not triggering the tap event ON THE ENTRY.

    If you have any idea of what i am doing wrong please let me know :)

  • forlayoforlayo Member

    You can do it setting a boxview over the entry and then giving the gesture recognizer to this last one.

                <Grid>
                    <Entry 
                        Text="{Binding TimeIn, StringFormat='{0:HH:mm}'}"
                        Placeholder="In" 
                        VerticalOptions="Center"
                        IsReadOnly="True"
                        Margin="10,0,10,0"
                        />
                    <BoxView HorizontalOptions="FillAndExpand">
                        <BoxView.GestureRecognizers>
                            <TapGestureRecognizer
                            Tapped="TapGestureRecognizer_Tapped"
                            NumberOfTapsRequired="1">
                            </TapGestureRecognizer>
                        </BoxView.GestureRecognizers>
                    </BoxView>
                </Grid>
    

    Obviously this will avoid you giving the focus to the entry, but it's something you can do on your gesture recogniser. I hope this helps someone :smile:

  • JTOneJTOne USMember ✭✭

    xamarin forms control

    public class TappableEntry : Entry
    {
        public static BindableProperty TapProperty = BindableProperty.Create(nameof(Tap), typeof(ICommand), typeof(TappableEntry), null, BindingMode.OneWay);
        public ICommand Tap
        {
            get { return (ICommand)GetValue(TapProperty); }
            set { SetValue(TapProperty, value); }
        }
    
        public static readonly BindableProperty TapParameterProperty = BindableProperty.Create(nameof(TapParameter), typeof(object), typeof(TappableEntry), null, BindingMode.OneWay);
        public object TapParameter
        {
            get { return GetValue(TapParameterProperty); }
            set { SetValue(TapParameterProperty, value); }
        }
    }
    

    uwp renderer

    public class TappableEntryRenderer : EntryRenderer
    {
        private readonly TappedEventHandler tappedEventHandler;
        private TappableEntry theElement;
    
        public TappableEntryRenderer()
        {
            tappedEventHandler = new TappedEventHandler(Control_Tapped);
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            var element = e.NewElement as TappableEntry;
            if (element != null && Control != null)
            {
                theElement = element;
                Control.RemoveHandler(TappedEvent, tappedEventHandler);
                Control.AddHandler(TappedEvent, tappedEventHandler, true);
            }
        }
    
        private void Control_Tapped(object sender, TappedRoutedEventArgs e)
        {
            theElement?.Tap?.Execute(theElement.TapParameter);
        }
    }
    

    android renderer

    public class TappableEntryRenderer : EntryRenderer
    {
        private TappableEntry theElement;
    
        public TappableEntryRenderer(Context context) : base(context)
        {
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            var element = e.NewElement as TappableEntry;
            if (element != null && Control != null)
            {
                theElement = element;
    
                Control.Click -= Control_Click;
                Control.Click += Control_Click;
            }
        }
    
        private void Control_Click(object sender, System.EventArgs e)
        {
            theElement?.Tap?.Execute(theElement.TapParameter);
        }
    }
    
  • Hi Guys I just found a simple way that works with label and entry controls.
    The "NavigateCommand" is Bind to the ViewModel File and there is defined the function.

       <StackLayout>
            <StackLayout.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding NavigateCommand}"/>
            </StackLayout.GestureRecognizers>
            <Entry Placeholder="ingresa el nombre de quien quieres reconocer" IsEnabled="False"/>
        </StackLayout>
    
  • AnatolyPashmorhaAnatolyPashmorha UAMember ✭✭

    to implement Tap with wrapper you should add Entry.InputTransparent = true; to the Entry.

Sign In or Register to comment.