How to disable double tap on a button into android

Hello all,

i develop an cross mobile application and i have a problem, when a user tap twice on a button which launch a contentPage to scanner a QRCode my application crash. I understrand why, but how can i disable a double tap on this button ? I've try to disable this button, to remove delegate but it's always the same problem and i don't found any solution at my issue....so, if you've some idea to solve my problem... Thanks :)

Answers

  • ashalvaashalva GEMember ✭✭✭

    @JonathanRoze, so when first click fires disabling the button does not solve the problem? If the problem still occurs it means that the button is not disabled, so you should find the problem in a different place.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Post your code

    I use a variable set true or false instead of enable disable the button

  • JonathanRozeJonathanRoze FRMember

    @ashalva said:
    @JonathanRoze, so when first click fires disabling the button does not solve the problem? If the problem still occurs it means that the button is not disabled, so you should find the problem in a different place.

    No, because there is a delay :/ !

    @AlessandroCaliaro said:
    Post your code

    I use a variable set true or false instead of enable disable the button

    Yes :

        public void loadScanner(object sender, EventArgs e)
        {
            scannerQR.Clicked -= loadScanner;
                        scannIsEnabled = false;
            Navigation.PushModalAsync(scannerView);
    
             MessagingCenter.Subscribe<string>(this, "QRCODE", (args) =>
                    {
                    // Si le message est envoyé, on se desabonne
                    MessagingCenter.Unsubscribe<string>(this, "QRCODE");
    
                        QRCode qr = new QRCode(args);
                        API api = new API();
    
                        if (qr.Validate())
                        {
                            if (!api.getSession(qr.getPocID()))
                            {
                                DisplayAlert("Cette borne est déjà en cours d'utilisation", "", "OK");
                            }
    
                            else {
                                DisplayAlert("Chargement de la page!", args, "OK");
                                Borne bornView = new Borne(qr);
                                Navigation.PushAsync(bornView);
                            }
    
                        }
    
    
    
                        else {
    
                            DisplayAlert("Le QRCode n'est pas compatible!", args, "OK");
                        }
    
    
                    });
    
            this.scannerQR.Clicked += loadScanner;
            this.IsEnabled = true;
    
    }
    

    So, when a tap twice on the button, boum, crash because two contentpage are instanciate !

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    For example if you have a isbuttonpressed global variable you can write something like

    If isbuttonpressed then
    Return
    Else
    Isbuttonpressed = true

    And at the end (before exiting the function)

    Isbuttonpressed= false

    Sorry but I am posting from my iPhone phone...

    Can you use await for pushmodal?

  • JonathanRozeJonathanRoze FRMember

    Mhh it's seem a good idea, i go to try this !

    Yes for my test, i remove ^^' !

  • JonathanRozeJonathanRoze FRMember

    The problem is the same... If the user tap fast on the button, crash :( !

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Have you tried with async await?

  • ClowningClowning USMember ✭✭

    @AlessandroCaliaro said:
    Have you tried with async await?

    With async and await, it's good :D ! Thanks

    And.... Can you able to explain me, async / await clearly ?:hushed:

  • ClowningClowning USMember ✭✭

    @AlessandroCaliaro because i have another problem, when my scanner found the QRCode he send a message (MessagingCenter) and the parent waiting for this data, but the checking into the MessagingCenter.Subscribe the methode api.getSession(qr.getPocID()) take some time and my scanner content page doesn't disappear... Only after the processing..

  • ClowningClowning USMember ✭✭

    Thanks :) ! So do you have an idea to solve my second problem ? ahah

    To sum up :

    • Click button
    • Scanner is launch
    • Scanner found the QRCode and save the value
    • Send the value
    • The parent get the value
    • Processing via my library
    • Scanner close

    And i want this :

    • Click button
    • Scanner is launch
    • Scanner found the QRCode and save the value
    • Send the value
    • Scanner close
    • The parent get the value
    • Processing via my library
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Can you post on github a sample project so we can test it?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Interesting post of @PeterFoot

    http://j.mp/1OY15j2

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @JonathanRoze.0248 if you have an answer you should add a Like to the answer

  • CezaryGrabskiCezaryGrabski USMember

    I am solving that problem with Clicked handler where I check and set variable "_isBusy" and it is working for me.
    I use one variable for all buttons (in listview for example) so user cannot fire more that one command at once.

  • JoshuaLatusiaJoshuaLatusia USMember ✭✭

    I Solved this problem with all of my events by creating a static class which registers when an event is fired.
    What it does is save the event by a name and the time it fires. And everytime you fire another event it checks if the Event should or should not fire by checking if the event that is firing is on the list.

    /// <summary>
    /// Struct for storing an fired event by identifier and time
    /// </summary>
    public struct DebouncedEvent
    {
        private DateTime LastBounce;
        private string Identifier;
    }
    
    /// <summary>
    /// Limits Events from firing multiple times by tracking last time they were fired
    /// </summary>
    public static class EventDebouncer
    {
        private static List<DebouncedEvent> eventList = new List<DebouncedEvent>();
    
        public static List<DebouncedEvent> EventList { get => eventList; set => eventList = value; }
    
        /// <summary>
        /// Determines if event should be fired or not
        /// </summary>
        /// <param name="id">The identifier of the event.</param>
        /// <returns>If event may be fired</returns>
        public static bool ShouldBounce(string id)
        {
            ClearEventList();
    
            if (EventList.Any(x => x.Identifier.Equals(id)))
            {
                return false;
            }
            else
            {
                EventList.Add(new DebouncedEvent { Identifier = id, LastBounce = DateTime.Now });
                return true;
            }
        }
    
        /// <summary>
        /// Note Replace 2000 by delay in milliSeconds you want.
        /// Removes Event from the list when it can fire again
        /// </summary>
        private static void ClearEventList()
        {
            EventList.RemoveAll(x => (DateTime.Now - x.LastBounce).TotalMilliseconds > 2000);
        }
    }
    

    Then you put this code in the button on click events.

    /// The event you don't want to fire multiple times
    private void SomeClickEvent(object sender, EventArgs e)
    {
        if (!EventDebouncer.ShouldBounce("SomeName"))
            return;
    
        // Do stuff
    }
    

    This will check if the event may be fired or not by looking at the DebouncedEvent list.

Sign In or Register to comment.