Один щелчок и двойной щелчок кнопки в Android

В моем приложении у меня есть кнопка. После однократного и двойного нажатия кнопки будет выполнена отдельная операция. Как я могу это сделать? Спасибо

12 ответов

Ну просто просто переопределить.

onClick метод OnClickListener

public abstract class DoubleClickListener implements View.OnClickListener {
private static final long DEFAULT_QUALIFICATION_SPAN = 200;
private boolean isSingleEvent;
private long doubleClickQualificationSpanInMillis;
private long timestampLastClick;
private Handler handler;
private Runnable runnable;

public DoubleClickListener() {
    doubleClickQualificationSpanInMillis = DEFAULT_QUALIFICATION_SPAN;
    timestampLastClick = 0;
    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            if (isSingleEvent) {
                onSingleClick();
            }
        }
    };
}

@Override
public void onClick(View v) {
    if((SystemClock.elapsedRealtime() - timestampLastClick) < doubleClickQualificationSpanInMillis) {
        isSingleEvent = false;
        handler.removeCallbacks(runnable);
        onDoubleClick();
        return;
    }

    isSingleEvent = true;
    handler.postDelayed(runnable, DEFAULT_QUALIFICATION_SPAN);
    timestampLastClick = SystemClock.elapsedRealtime();
}

public abstract void onDoubleClick();
public abstract void onSingleClick();
}

Применение

 button.setOnClickListener(new DoubleClickListener() {
        @Override
        public void onDoubleClick() {
            Log.i("onClick", "double");
        }

        @Override
        public void onSingleClick() {
            Log.i("onClick", "single");
        }
    });

Возможно, вам потребуется создать переменную задержки, которая будет различать один щелчок и двойной щелчок.

Смотрите этот код,

private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis
private long lastPressTime;

private boolean mHasDoubleClicked = false;

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {    

        // Get current time in nano seconds.
        long pressTime = System.currentTimeMillis();


        // If double click...
        if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
            Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show();
            mHasDoubleClicked = true;
        }
        else {     // If not double click....
            mHasDoubleClicked = false;
            Handler myHandler = new Handler() {
                 public void handleMessage(Message m) {
                      if (!mHasDoubleClicked) {
                            Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show();
                      }
                 }
            };
            Message m = new Message();
            myHandler.sendMessageDelayed(m,DOUBLE_PRESS_INTERVAL);
        }
        // record the last time the menu button was pressed.
        lastPressTime = pressTime;      
        return true;
    }

Возможно, вы захотите не использовать DoubleTap. Это не нормальное поведение Android.

Когда я впервые начал программировать на Android, я продолжал сталкиваться с вещами, которые действительно были "трудными" для Android. Со временем я обнаружил, что многие из них были трудными, потому что это была довольно плохая идея.

Если вы портируете приложение для iOS или эмулируете поведение приложения для iOS, вы можете рассмотреть возможность преобразования пользовательского интерфейса в поведение в стиле Android и использовать longPress или другие жесты "androidy".

Вот похожий вопрос и ответ:

Android: как обнаружить двойной тап?

Вы должны реализовать GestureDetector и поместить свой код в single/double click,

TestActivity.java

iv.setOnClickListener(new OnClickListener() {           
                @Override
                public void onClick(View v) {
                    //putyour first activity call.
                }
    }

iv.setOnTouchListener(new OnTouchListener() {
             GestureDetector gestureDetector = new GestureDetector(context, new MyGestureDetector(context));
         @Override
         public boolean onTouch(View v, MotionEvent event) {
                return gestureDetector.onTouchEvent(event);
         }
});

Теперь вы должны создать GestureDetector.java учебный класс.

public class MyGestureDetector extends SimpleOnGestureListener {
    public Context context;
    public String phno;

    public MyGestureDetector(Context con) {
        this.context=con;       
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return super.onDown(e);
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        System.out.println("in Double tap");

        return true;
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        System.out.println("in single tap up");
            //put your second activity.
        return super.onSingleTapUp(e);
    }   
}

Спасибо @NikolaDespotoski.

Вы можете проверить пример DOUBLE-TAP по следующему URL. что используется в listView. Я надеюсь, что это полезно для вас.

https://nodeload.github.com/NikolaDespotoski/DoubleTapListView/zip/master

Хотя уже слишком поздно, но любой может понять, увидят ли они это.

int number_of_clicks = 0;
boolean thread_started = false;
final int DELAY_BETWEEN_CLICKS_IN_MILLISECONDS = 250;

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ++number_of_clicks;
        if(!thread_started){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    thread_started = true;
                    try {
                        Thread.sleep(DELAY_BETWEEN_CLICKS_IN_MILLISECONDS);
                        if(number_of_clicks == 1){
                            client.send(AppHelper.FORMAT_LEFT_CLICK);
                        } else if(number_of_clicks == 2){
                            client.send(AppHelper.FORMAT_DOUBLE_CLICK);
                        }
                        number_of_clicks = 0;
                        thread_started = false;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
});

Объяснение:


Перед нажатием кнопки number_of_click инициализируется в 0. thread_started - флаг, определяющий, был ли запущен поток раньше или нет. Теперь, при нажатии кнопки, увеличьте количество нажатий кнопки с помощью инкрементного оператора. проверьте, запущен ли ранее поток или нет, если нет, то запустите поток. В теме примените свою логику с помощью number_of_clicks. и поток будет ждать следующих миллисекунд, а затем пройдет через вашу логику. Итак, теперь вы можете применить столько кликов, сколько хотите.

Это ответ @saksham в Котлине.

      abstract class DoubleClickListener : View.OnClickListener {
    private val DEFAULT_QUALIFICATION_SPAN = 200L
    private var isSingleEvent = false
    private val doubleClickQualificationSpanInMillis =
        DEFAULT_QUALIFICATION_SPAN
    private var timestampLastClick = 0L
    private val handler = Handler(Looper.getMainLooper())
    private val runnable: () -> Unit = {
        if (isSingleEvent) {
            onSingleClick()
        }
    }
    override fun onClick(v: View) {
        if (SystemClock.elapsedRealtime() - timestampLastClick < doubleClickQualificationSpanInMillis) {
            isSingleEvent = false
            handler.removeCallbacks(runnable)
            onDoubleClick()
            return
        }
        isSingleEvent = true
        handler.postDelayed(runnable, DEFAULT_QUALIFICATION_SPAN)
        timestampLastClick = SystemClock.elapsedRealtime()
    }

    abstract fun onDoubleClick()
    abstract fun onSingleClick()
}

двойной щелчок и одиночный щелчок в Android

Решение, которое подходит практически для всех версий

Обнаружение типа события в пределах стандартной продолжительности , которую вы хотите определить. Он может обнаруживать событие ускоренным и последовательным образом , например, прохождение видео в течение определенного периода.

      //general definition
private CountDownTimer countDownTimer;
private int click_duble = 1;

button.setOnClickListener(view -> {

    if (countDownTimer == null) {
        float Second= (float) 0.25; //Detecting the type of event within a quarter of a second
        countDownTimer= new CountDownTimer((long) (Second * 1000), 50) {
            @Override public void onTick(long l){}
            @Override
            public void onFinish() {
                if (click_duble >= 2) {
                    Toast.makeText(player_fb.this, "Double", Toast.LENGTH_SHORT).show();

                } else {
                    Toast.makeText(player_fb.this, "Single", Toast.LENGTH_SHORT).show();
                }
                click_duble = 1;
                countDownTimer = null;
            }};countDownTimer.start();
    }else
        click_duble += 1;
});

Решение этой проблемы путем наследования от View.OnClickListener и проверки времени щелчка, чтобы различить один щелчок или двойной щелчок, это также решает проблему быстрого щелчка. Это решение принесет незначительное изменение кода, просто замените View.OnClickLister. Вы также можете переопределить getGap(), чтобы переопределить время между двумя кликами.

import android.os.SystemClock;
import android.view.View;

/*****
 * Implement to fix the double click problem.
 * Avoid the fast double click for button and images.
 */
public abstract class OnSingleClickListener implements View.OnClickListener {
    private long prevClickTime =0;

    @Override
    public void onClick(View v) {
        _onClick(v);
    }

    private synchronized void _onClick(View v){
        long current = SystemClock.elapsedRealtime();
        if(current-prevClickTime> getGap()){
            onSingleClick(v);
            prevClickTime = SystemClock.elapsedRealtime();
        }else {
            onDoubleClick(v);
            prevClickTime = 0;
        }
    }

    public abstract void onSingleClick(View v);
    public abstract void onDoubleClick(View v);

    /********
     *
     * @return The time in ms between two clicks.
     */
    public long getGap(){
        return 500L; //500ms
    }
}

Решение up не может работать для нескольких кликов, я протестировал его, но не смог.

Поэтому я предлагаю использовать RxBinding с ProgressDialog.

при нажатии на кнопку, показ хода выполнения не может быть отменен, исправьте это.

на котлине. добавить класс

      class OnSingleClickListener(private val delay: Long) : View.OnClickListener {

private var lastClickTime = 0L

override fun onClick(view: View) {
    val currentTime = System.currentTimeMillis()
    if (currentTime - lastClickTime < delay) {
        return
    }
    lastClickTime = currentTime
}}

и используйте расширение с регулируемой задержкой

      fun View.setOnSingleClickListener(delay: Long = 500L, block: () -> Unit{
setOnClickListener(OnSingleClickListener(delay, block))}

отсюда _

У меня тоже однажды возникла такая же проблема

setOnClickListener(new OnClickListener() {           
            @Override
            public void onClick(View v) {
                if(isFmOn()){
                   //stopFM
                }else{
                  //do other things
                }
            }
}

когда я нажал кнопку,FM остановился, но когда я дважды щелкнул,FM не остановился. Проблема заключалась в том, что при одиночном и двойном нажатии кнопки значение isFmOn() было разным. Я решил проблему с помощью этого:

setOnClickListener(new OnClickListener() {           
            @Override
            public void onClick(View v) {
                Thread.sleep(500);//500ms was enough to finish stopFM before the second click
                if(isFmOn()){
                   //stopFM
                }else{
                  //do other things
                }
            }
}
Другие вопросы по тегам