Android: How to do different events by touching a button and keeping it pressed?

1

I am working on an android project, where I need a button to perform 2 different actions in certain circumstances:

  • When you touch it (do not hold it down), do the event1.
  • When you hold down for 5 seconds, do the event2.
  • In the res / layout:

    <insat.aes.relojcontrol.ButtonInsat
                    android:id="@+id/Button01"
                    android:onClick="tapIniciarClase"
                    android:visibility="invisible"/>
    

    In the src:

    public void tapIniciarClase(View v)
    {
        _presentadorPrincipal.solicitarMostrarVistaIdentificacion(true);
    }
    

    It is worth mentioning that the code is not mine, this was one of the projects of someone who abandoned it and they left me in charge. That's everything related to the Button that I found in the code

        
    asked by Gonzalox2 05.04.2018 в 15:10
    source

    2 answers

    2

    To start, in your case, we must select the button in question, looking for your ID:

    Button boton = (Button) findViewById(R.id.Button01);
    

    To detect a short click on an element, a setOnClickListener listener must be launched on the element, to capture the onClick event.

    boton.setOnClickListener(new View.OnClickListener() {
        @Override
        public boolean onClick(View v) {
            //Pulsación corta
    
            return false;
        }
    });
    

    To detect a long click on an element, a listener must be launched setOnLongClickListener on the element, to capture the onLongClick event.

    boton.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            //Pulsación larga
    
            return false;
        }
    });
    

    I have read that you are looking for the event to occur after 5 seconds. The event LongClick (if I remember correctly) occurs at about 3 seconds and this value is unmovable (managed by Android). There is a little trick to be able to establish a long pulse of 5 seconds, using the Touch event and comparing the difference of milliseconds from when the button is pressed ( ACTION_DOWN ) until you stop pressing ( ACTION_UP ):

    long tiempoEnMS = 0;
    
    boton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                tiempoEnMS = (Long) System.currentTimeMillis();
            }
            else if(event.getAction() == MotionEvent.ACTION_UP){
                if(((Long) System.currentTimeMillis() - tiempoEnMS) >= 5000){
                    // Acción a realizar tras una pulsación de 5 segundos
    
                    return true;
                }
            }
            return false;
        }
    });
    


    EDIT 1:

    I show the complete code that I have made (MCVE). It is working correctly:

    package com.example.juan.aplicaciondeejemplo;
    
    import android.annotation.SuppressLint;
    import android.graphics.Color;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity {
    
    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        Button boton = (Button) findViewById(R.id.Button01);
    
        boton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int color;
                View contender = v.getRootView();
                color = Color.parseColor("#A5D6A7"); // Verde
                contender.setBackgroundColor(color);
                Log.i("Gonzalox2", "*Evento 1.");
            }
        });
    
    
        boton.setOnTouchListener(new View.OnTouchListener() {
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(event.getAction() == MotionEvent.ACTION_DOWN){
                    tiempoEnMS = (Long) System.currentTimeMillis();
                }
                else if(event.getAction() == MotionEvent.ACTION_UP){
                    if(((Long) System.currentTimeMillis() - tiempoEnMS) >= 5000){
                        // Acción a realizar tras una pulsación de 5 segundos
                        int color;
                        View contender = v.getRootView();
                        color = Color.parseColor("red"); // Rojo
                        contender.setBackgroundColor(color);
    
                        Log.i("Gonzalox2", "*Evento 2. Al mantener presionado por 5 segundos, haga el evento2.");
                        return true;
                    }
                }
                return false;
            }
        });
    
    }
    
    long tiempoEnMS = 0;
    }
    
        
    answered by 05.04.2018 / 15:17
    source
    0

    There is no event that can be called from the layout for onLongPressed only for click android:onClick="metodo" , therefore the solution is:

    Add a listener setOnTouchListener () to detect event 1 when detecting ACTION_DOWN . and use the same listener setOnTouchListener () to detect event 2, detecting the time it takes to play it. If you stop touching the button within 5 seconds, event 2 must be canceled.

    This is an example:

    //Declarar variable a nivel de clase para determinar si se cancela el evento que se llamaría hasta los 5 segundos. 
    private boolean cancelLongClick = false;
    
    ...
    ...
    
          Button myButton = (Button)findViewById(R.id.button01);
    
               myButton.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
    
                       if(event.getAction() == MotionEvent.ACTION_DOWN){
    
                            Log.i("Gonzalox2", "*Evento 1. Al tocarlo (no mantener presionado), haga el evento1.");
                           cancelLongClick = false;
    
                            new Handler().postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    if(!cancelLongClick) {
                                        Log.i("Gonzalox2", "*Evento 2. Al mantener presionado por 5 segundos, haga el evento2.");
                                    }else{
                                        Log.i("Gonzalox2", "*Evento 2. Cancelado.");
                                    }
                                }
                            }, 5000);
    
    
                        }else if(event.getAction() == MotionEvent.ACTION_UP) {
                            Log.i(TAG, "MotionEvent.ACTION_UP");
                            //Si se deja de tocar antes de 5 segundos cancela el evento.
                            cancelLongClick = true;
                        }
    
    
                        return true;
                    }
                });
    
        
    answered by 05.04.2018 в 18:38