Android Bir Düğmeye Çift Tıklamayı Önleme


177

Android'de bir düğmeye çift tıklamayı önlemenin en iyi yolu nedir?


3
Qezt'in çözümüne bakın sadece tamamen uygulanabilir
Gennadiy Ryabkin

3
Bu sayfayı ziyaret eden kişilerin setEnabled (false) kullanmanın dezavantajını bilmesi için qezt'in çözümü kabul edilmiş olmalıdır.
LoveForDroid

Son tıklama zamanı çözümünü kullanarak kütüphanemi deneyebilirsiniz: github.com/RexLKW/SClick
Rex Lam

1
@Androider lütfen en iyi cevabınızı değiştirin
Amir133

Yanıtlar:


87

setEnabled(false)Kullanıcının tekrar tıklaması güvenli olana kadar düğmeyi devre dışı bırakın .


47
setEnabled (false) yeterince "hızlı" çalışmıyor gibi görünüyor. Bir düğme için bir View.OnClickListener.onClick (görünüm) ayarladım. OnClick () 'de yaptığım ilk şey bir log-deyimi yazmak, 2. deyimi button.setEnabled (false). Emülatörde hızlı çift tıkladığınızda günlük ifadesinin iki kez göründüğünü görüyorum! Hemen arkasından bir setClickable (false) eklerken bile, günlük ifadesi iki kez görünür.
QQQuestions

Hmmm, belki onClick () 'in sonunda setEnabled (true)' a kadar olan kod o kadar hızlı yürütülüyor ki, tekrar etkinleştirildi ...
QQQuestions

91
Benzer bir sorun yaşadım. Yararlı bir beyefendiye göre, Android aslında tıklamaları sıraya koyar, bu nedenle onClick () kodunuzun ne kadar hızlı veya yavaş çalıştığının önemi yoktur; sadece düğmeye ne kadar hızlı tıklarsanız. Yani. Düğmeyi zaten devre dışı bırakmış olabilirsiniz, ancak tıklama kuyruğu zaten iki veya üç tıklama ile doldurulmuş ve düğmeyi devre dışı bırakmanın kuyruğa alınan tıklamaların yayınlanması üzerinde hiçbir etkisi yoktur. (belki de olmalı?)
Nick

3
'Birini' gördüğünüzde o nadir an, sorulan soruya abstraaaaaaaact cevapları değil, tam bir cevap verir ..: P
Rahul

bu her zaman doğru çözüm değildir. OnClick'iniz pahalı bir işlemse, düğme yeterince hızlı devre dışı kalmaz. Tam geçirmez çözüm IMHO, son tıklama süresini kullanmaktır, ancak işlemin bir süre devam etmesini beklerseniz (giriş gibi) kullanıcının tekrar dokunmasını önlemek için düğmeyi devre dışı bırakır.
Sarang

368

tıklarken son tıklama zamanını kaydetmek bu sorunu önler.

yani

private long mLastClickTime = 0;

...

// inside onCreate or so:

findViewById(R.id.button).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // mis-clicking prevention, using threshold of 1000 ms
        if (SystemClock.elapsedRealtime() - mLastClickTime < 1000){
            return;
        }
        mLastClickTime = SystemClock.elapsedRealtime();

        // do your magic here
    }
}

21
Çift tıklamayı gerçekten engelleyen tek çözüm budur. Ben sadece bir saat geçirdim, çünkü bu yöntem oldukça tıknaz, ama hiçbiri bu dışında bir görünüm hızlı bir çift dokunma önleyebilir. Google lütfen bunu düzeltin :)
ashishduh

6
Bu çözüm, ekranda birden çok düğmeniz olduğunda ve aynı anda yalnızca tek bir düğmeyi tıklatmak istediğinizde de çalışır.
geçersiz

12
Bu, yeterince hızlı çift tıklarsanız çift tıklamayı tamamen önlemez.
Loc

4
En iyi cevap,
zirvede

3
Bu çözüm doğru cevap olmalı ... setEnabled (false) yeterli değil.
heloisasim

55

Benim çözümüm

package com.shuai.view;

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

/**
 * 处理快速在某个控件上双击2次(或多次)会导致onClick被触发2次(或多次)的问题
 * 通过判断2次click事件的时间间隔进行过滤
 * 
 * 子类通过实现{@link #onSingleClick}响应click事件
 */
public abstract class OnSingleClickListener implements View.OnClickListener {
    /**
     * 最短click事件的时间间隔
     */
    private static final long MIN_CLICK_INTERVAL=600;
    /**
     * 上次click的时间
     */
    private long mLastClickTime;

    /**
     * click响应函数
     * @param v The view that was clicked.
     */
    public abstract void onSingleClick(View v);

    @Override
    public final void onClick(View v) {
        long currentClickTime=SystemClock.uptimeMillis();
        long elapsedTime=currentClickTime-mLastClickTime;
        //有可能2次连击,也有可能3连击,保证mLastClickTime记录的总是上次click的时间
        mLastClickTime=currentClickTime;

        if(elapsedTime<=MIN_CLICK_INTERVAL)
            return;

        onSingleClick(v);        
    }

}

Kullanım OnClickListener ile benzerdir, bunun yerine onSingleClick () öğesini geçersiz kılar:

mTextView.setOnClickListener(new OnSingleClickListener() {
            @Override
            public void onSingleClick(View v) {
                if (DEBUG)
                    Log.i("TAG", "onclick!");
            }
     };

1
Çift dokunmayı otomatik olarak önlemek için kolay ve mükemmel.
Benjamin Piette

1
Bu, yeterince hızlı çift tıklarsanız çift tıklamayı tamamen önlemez.
Loc

1
Harika bir çözüm. MIN_CLICK_INTERVAL = 1000 değerini değiştirdim;
Nizam

5
Her 0,5 saniyede bir doğru bir şekilde düğmeye basacak olsaydım, müteakip tıklamalarımdan hiçbiri gerçekleşmeyecekti çünkü mLastClickTime her tıklama güncellenecekti. Benim önerim, aralığı kontrol ettikten sonra mLastClickTime atamak olacaktır.
k2col

mLastClickTime currentClickTime =; (elapsedTime <= MIN_CLICK_INTERVAL) döndürüldükten sonra yerleştirilmelidir;
Loyea

41

Düğme devre dışı bırakılmadan önce tıklama olayları sıraya alınabileceğinden, onClick () üzerinde hesaplama yoğun olarak çalışıyorsanız, düğmeyi devre dışı bırakmak veya seçilemez olarak ayarlamak yeterli değildir. OnClickListener uygulayan geçersiz kılınabilir, sıraya alınmış tıklamaları yoksayarak bu sorunu gideren soyut bir temel sınıf yazdım:

/** 
 * This class allows a single click and prevents multiple clicks on
 * the same button in rapid succession. Setting unclickable is not enough
 * because click events may still be queued up.
 * 
 * Override onOneClick() to handle single clicks. Call reset() when you want to
 * accept another click.
 */
public abstract class OnOneOffClickListener implements OnClickListener {
    private boolean clickable = true;

    /**
     * Override onOneClick() instead.
     */
    @Override
    public final void onClick(View v) {
        if (clickable) {
            clickable = false;
            onOneClick(v);
            //reset(); // uncomment this line to reset automatically
        }
    }

    /**
     * Override this function to handle clicks.
     * reset() must be called after each click for this function to be called
     * again.
     * @param v
     */
    public abstract void onOneClick(View v);

    /**
     * Allows another click.
     */
    public void reset() {
        clickable = true;
    }
}

Kullanım OnClickListener ile aynıdır, ancak bunun yerine OnOneClick () öğesini geçersiz kılın:

OnOneOffClickListener clickListener = new OnOneOffClickListener() {
    @Override
    public void onOneClick(View v) {

        // Do stuff

        this.reset(); // or you can reset somewhere else with clickListener.reset();
    }
};
myButton.setOnClickListener(clickListener);

Kod için teşekkürler. Burada yazdıklarınıza dayanarak, düğme veya üst öğesi gizliyse tıklamaları önleyen benzer bir sınıf yaptım - tıklamanın hemen ardından düğmeyi gizleseniz bile Android'in tıklamaları kuyruğa alması komik.
nikib3ro

1
Benzer bir çözüm var - sadece bu sınıfı xml'de kullanabilirsiniz ve sizin için clickListeners'ı sarar github.com/doridori/AndroidUtilDump/blob/master/android/src/…
Dori

2
Bu iyi bir çözümdür, ancak onClick () ve reset () senkronize edilmelidir, aksi takdirde çift tıklama yine de gizlice girebilir.
Tom anMoney

6
@TomanMoney, nasıl? Tüm tıklama etkinlikleri tek bir kullanıcı arayüzünde gerçekleşmez mi?
Ken

@Dori bağlantı öldü
naXa

36

Kotlin Uzatma Fonksiyonları ve RxBinding ile çok süslü bir şekilde yapabilirsiniz

   fun View.clickWithDebounce(debounceTime: Long = 600L, action: () -> Unit): Disposable =
        RxView.clicks(this)
                .debounce(debounceTime, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe { action() }

veya

fun View.clickWithDebounce(debounceTime: Long = 600L, action: () -> Unit) {
    this.setOnClickListener(object : View.OnClickListener {
        private var lastClickTime: Long = 0

        override fun onClick(v: View) {
            if (SystemClock.elapsedRealtime() - lastClickTime < debounceTime) return
            else action()

            lastClickTime = SystemClock.elapsedRealtime()
        }
    })
}

ve sonra sadece:

View.clickWithDebounce{ Your code }

engenering
Serg Burlaka

3
Rx için Debounce burada iyi çalışmaz. Bunun yerine "ThrottleFirst" daha iyi uymalıdır. demo.nimius.net/debounce_throttle burada nasıl farklılık gösterdiklerine bir örnektir. PS: ve aslında clickWithDebounce uygulamanız gazdan arındırma değil, geri dönme değil
krossovochkin

13

Ben de benzer bir problemle karşılaşıyorum, bazen 2 kez tıkladığı bazı datepicker ve zamanlayıcıları gösteriyordum. Bunu bununla çözdüm

long TIME = 1 * 1000;
@Override
public void onClick(final View v) {
v.setEnabled(false);

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            v.setEnabled(true);
        }
    }, TIME);
}

İhtiyacınıza göre zamanı değiştirebilirsiniz. Bu yöntem benim için işe yarıyor.


Bu gerçek çözümdür, çünkü süre geçtikten sonra düğmeyi otomatik olarak yeniden etkinleştirir. Diğer çözümler hızlı bir şekilde iki kez tıklarsanız düğmeyi kalıcı olarak engeller. Bu çözüm sorunu çözer! Teşekkürler
Néstor

10

setEnabled(false) benim için mükemmel çalışıyor.

Fikir, { setEnabled(true); }başlangıçta yazıyorum ve sadece falsedüğmenin ilk tıklamasında yapıyorum .


9

Eski bir soru olduğunu biliyorum, ama bu ortak sorunu çözmek için bulduğum en iyi çözümü paylaşıyorum

        btnSomeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // Prevent Two Click
            Utils.preventTwoClick(view);
            // Do magic
        }
    });

Ve Utils.java gibi başka bir dosyada

    /**
 * Método para prevenir doble click en un elemento
 * @param view
 */
public static void preventTwoClick(final View view){
    view.setEnabled(false);
    view.postDelayed(new Runnable() {
        public void run() {
           view.setEnabled(true);
        }
    }, 500);
}

8

Bu sorunun asıl çözümü, düğmeyi grileştiren setEnabled (false) ve ikinci tıklamanın alınamamasını sağlayan setClickable (false) kullanmaktır. Bunu test ettim ve çok etkili görünüyor.


7

Birisi hala kısa bir cevap arıyorsa aşağıdaki kodu kullanabilirsiniz

 private static long mLastClickTime = 0;
  if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { // 1000 = 1second
         return;
    }
 mLastClickTime = SystemClock.elapsedRealtime();

Bu kod if statement, kullanıcı her tıkladığında içeri girer View within 1 secondve ardından return;başlatılır ve diğer kod başlatılmaz.


2
Bu kabul edilen cevap olmalı. Süper basit ve çok hızlı tıklasanız bile çalışır! Bunun için teşekkürler.
Geoffroy CALA

7

K leanest Kotlin deyimsel yol:

class OnSingleClickListener(private val block: () -> Unit) : View.OnClickListener {

    private var lastClickTime = 0L

    override fun onClick(view: View) {
        if (SystemClock.elapsedRealtime() - lastClickTime < 1000) {
            return
        }
        lastClickTime = SystemClock.elapsedRealtime()

        block()
    }
}

fun View.setOnSingleClickListener(block: () -> Unit) {
    setOnClickListener(OnSingleClickListener(block))
}

Kullanımı:

button.setOnSingleClickListener { ... }

6

Benim çözümüm bir booleandeğişken kullanmaya çalışın :

public class Blocker {
    private static final int DEFAULT_BLOCK_TIME = 1000;
    private boolean mIsBlockClick;

    /**
     * Block any event occurs in 1000 millisecond to prevent spam action
     * @return false if not in block state, otherwise return true.
     */
    public boolean block(int blockInMillis) {
        if (!mIsBlockClick) {
            mIsBlockClick = true;
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mIsBlockClick = false;
                }
            }, blockInMillis);
            return false;
        }
        return true;
    }

    public boolean block() {
        return block(DEFAULT_BLOCK_TIME);
    }
}

Ve aşağıdaki gibi kullanarak:

view.setOnClickListener(new View.OnClickListener() {
            private Blocker mBlocker = new Blocker();

            @Override
            public void onClick(View v) {
                if (!mBlocker.block(block-Time-In-Millis)) {
                    // do your action   
                }
            }
        });

GÜNCELLEME : Kotlin çözümü, görünüm uzantısını kullanma

fun View.safeClick(listener: View.OnClickListener, blockInMillis: Long = 500) {
    var lastClickTime: Long = 0
    this.setOnClickListener {
        if (SystemClock.elapsedRealtime() - lastClickTime < blockInMillis) return@setOnClickListener
        lastClickTime = SystemClock.elapsedRealtime()
        listener.onClick(this)
    }
}

5

Click Guard Tereyağı Bıçağı ile iyi çalışır

ClickGuard.guard(mPlayButton);

4
düğmesini çift tıklama için ayrı linrarye? ha
Serg Burlaka

Bunu özel düğmenin içinde kullanabilir miyim?
Ara Badalyan

@AraBadalyan 'içeride' ile ne demek istiyorsun. Sadece özel düğme koruma yöntemi için param olarak geçmek. Ardından düğmeniz çift tıklamaya karşı korunacaktır
thanhbinh84

Yani onclick kullanan tüm etkinliklere ClickGuard.guard (mPlayButton) eklemek istemiyorum. CustomButton genişlik Düğmesi oluşturmak ve CustomButton içine ClickGuard koymak istiyorum. Ancak CustomButton yapıcısına ClickGuard eklediğimde işe yaramadı.
Ara Badalyan

@AraBadalyan doğru. Bu şekilde çalışmaz.
thanhbinh84

5

benim durumumda bir düğme görünümü kullanıyordum ve çok hızlı bir şekilde tıklama alıyordu. tıklanabilirliği devre dışı bırakın ve birkaç saniye sonra tekrar etkinleştirin ...

Temelde ben Views onClickListener etrafında sarar bir sarıcı sınıf yaptı. isterseniz özel bir gecikme de ayarlayabilirsiniz.

public class OnClickRateLimitedDecoratedListener implements View.OnClickListener {

    private final static int CLICK_DELAY_DEFAULT = 300;
    private View.OnClickListener onClickListener;
    private int mClickDelay;


        public OnClickRateLimitedDecoratedListener(View.OnClickListener onClickListener) {
            this(onClickListener, CLICK_DELAY_DEFAULT);
        }

        //customize your own delay
        public OnClickRateLimitedDecoratedListener(View.OnClickListener onClickListener, int delay) {
            this.onClickListener = onClickListener;
            mClickDelay = delay;
        }

        @Override
        public void onClick(final View v) {
            v.setClickable(false);
            onClickListener.onClick(v);

            v.postDelayed(new Runnable() {
                @Override
                public void run() {
                    v.setClickable(true);
                }
            }, mClickDelay);
        }
    }

ve sadece şunu söylemek için:

mMyButton.setOnClickListener(new OnClickRateLimitedDecoratedListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 doSomething();
             }
         }));

veya kendi gecikmenizi sağlayın:

 mMyButton.setOnClickListener(new OnClickRateLimitedDecoratedListener(new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
                         doSomething();
                     }
                 },1000));

GÜNCELLEME: RxJava çok yaygın olduğu için şimdi biraz eski moda. Diğerlerinin de belirttiği gibi, android'de tıklamaları yavaşlatmak için bir gaz kullanabiliriz. İşte bir örnek:

 RxView.clicks(myButton)
                    .throttleFirst(2000, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
                    .subscribe {
                        Log.d("i got delayed clicked")
                    }
        }

bu kütüphaneyi bunun için kullanabilirsiniz: implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'


4
    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            //to prevent double click
            button.setOnClickListener(null);
        }
    });

4

Bu yöntemi kullanabilirsiniz. Sonradan gecikmeyi kullanarak çift tıklama olaylarına dikkat edebilirsiniz.

void debounceEffectForClick (Görünüm görünümü) {

    view.setClickable(false);

    view.postDelayed(new Runnable() {
        @Override
        public void run() {
            view.setClickable(true);

        }
    }, 500);
}

4

Kısa satır içi kod ve değişken çift tıklama bekleme sürelerine izin veren kotlin uzantısı

fun View.setDoubleClickListener(listener: View.OnClickListener, waitMillis : Long = 1000) {
    var lastClickTime = 0L
    setOnClickListener { view ->
        if (System.currentTimeMillis() > lastClickTime + waitMillis) {
            listener.onClick(view)
            lastClickTime = System.currentTimeMillis()
        }
    }
}

Kullanımı:

anyView.setNoDoubleClickListener(View.OnClickListener { v ->
    // do stuff
})

Veya

anyView.setNoDoubleClickListener(View.OnClickListener { v ->
    // do stuff
}, 1500)

Harika, herkes bunu kullanmalı, kesinlikle güzel bir kod parçası ve herkesin kotlin'e taşınması için harika bir neden.
Achmad Naufal Syafiq

WaitMillis sadece kodlanmışsa daha güzel olabilir, o zaman dış parantezler ortadan kaldırılabilir.
WindRider

4

Aşağıdaki kod, kullanıcının birkaç saniye içinde birden çok kez tıklamasını önler ve yalnızca 3 saniye sonra izin verir.

private long lastClickTime = 0;

View.OnClickListener buttonHandler = new View.OnClickListener() {
    public void onClick(View v) {
        // preventing double, using threshold of 3000 ms
        if (SystemClock.elapsedRealtime() - lastClickTime < 3000){
            return;
        }

        lastClickTime = SystemClock.elapsedRealtime();
    }
}

3

Tıklama dinleyicilerinizi onResume içinde ayarlamak ve onPause'da null yapmak, hile de yapar.


3

Benim için sadece zaman damgasını hatırlamak ve buna karşı kontrol etmek (önceki tıklamadan bu yana 1 saniyeden fazla geçti) yardımcı oldu.


3

Umarım bu size yardımcı olabilir, kodu olay işleyicisine koyun.

// ------------------------------------------------ --------------------------------

    boolean hasTag = null != which.getTag( R.id.preventing_double_click_tag );

    if ( hasTag ) {
        // Do not handle again...
        return;
    } else {
        which.setTag( R.id.action, Boolean.TRUE );

        which.postDelayed( new Runnable() {
            @Override
            public void run() {
                which.setTag( R.id.action, null );
                Log.d( "onActin", " The preventing double click tag was removed." );
            }

        }, 2000 );
    }

3

OnClick yöntemi hemen dönmezse, bu önerilerin hiçbirinin işe yaramadığını gördüm. Touch olayı Android tarafından kuyruğa alınır ve bir sonraki onClick yalnızca ilk olay bittikten sonra çağrılır. (Bu bir UI iş parçacığı üzerinde yapıldığı için bu gerçekten normaldir.) OnClick işlevinin bittiği zamanı + bir boolean değişkeni verilen onClick'in çalışıp çalışmadığını işaretlemek için kullanmam gerekiyordu. Her iki işaretleyici özelliği de herhangi bir onClickListener'ın aynı anda çalışmasını önlemek için statiktir. (Kullanıcı başka bir düğmeyi tıklarsa) OnClickListener'ınızı bu sınıfa kolayca yerleştirebilirsiniz ve onClick yöntemini uygulamak yerine abstract oneClick () yöntemini uygulamanız gerekir.

    abstract public class OneClickListener implements OnClickListener {

    private static boolean started = false;
    private static long lastClickEndTime = 0;

    /* (non-Javadoc)
     * @see android.view.View.OnClickListener#onClick(android.view.View)
     */
    @Override
    final public void onClick(final View v) {
        if(started || SystemClock.elapsedRealtime()-lastClickEndTime <1000 ){
            Log.d(OneClickListener.class.toString(), "Rejected double click, " + new Date().toString() );
            return; 
        }
        Log.d(OneClickListener.class.toString(), "One click, start: " + new Date().toString() );
        try{
            started = true;
            oneClick(v);
        }finally{
            started = false;
            lastClickEndTime = SystemClock.elapsedRealtime();
            Log.d(OneClickListener.class.toString(), "One click, end: " + new Date().toString() );
        }
    }

    abstract protected void oneClick(View v);
}

3

bunu yapmak için jake wharton tarafından rx bağlamaları da kullanabilirsiniz . arka arkaya tıklamalar arasında 2 saniye dolduran bir örnek:

RxView.clicks(btnSave)
                .throttleFirst(2000, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept( Object v) throws Exception {
//handle onclick event here
                });

// not: Bu durumda Object v'yi görmezden gelin ve her zaman düşünüyorum.


3

Kotlin sınıfı SafeClickListener oluştur

class SafeClickListener(
        private var defaultInterval: Int = 1000,
        private val onSafeCLick: (View) -> Unit
) : View.OnClickListener {
    private var lastTimeClicked: Long = 0    override fun onClick(v: View) {
        if (SystemClock.elapsedRealtime() - lastTimeClicked < defaultInterval) {
            return
        }
        lastTimeClicked = SystemClock.elapsedRealtime()
        onSafeCLick(v)
    }
}

baseClass veya başka bir işlev oluşturun

fun View.setSafeOnClickListener(onSafeClick: (View) -> Unit) {val safeClickListener = SafeClickListener {
        onSafeClick(it)
    }
    setOnClickListener(safeClickListener)
}

ve düğme tıklamasıyla kullanın

btnSubmit.setSafeOnClickListener {
    showSettingsScreen()
}

1
Uzantılarla en temiz çözüm! Teşekkürler!
android_dev



2

Tıklanabilir değerini false olarak ayarlamak ilk çift tıklamada çalışmaz, ancak sonraki çift tıklama engellenir. Sanki yükleme tıklaması delegesi ilk kez daha yavaştır ve ikinci tıklama ilk tamamlanmadan önce yakalanır.

        Button button = contentView.FindViewById<Button>(Resource.Id.buttonIssue);
        button.Clickable = false;
        IssueSelectedItems();
        button.Clickable = true;

2

Bu sorunu biri @ jinshiyi11'e benzer iki clas kullanarak düzeltirim ve anoter açık tıklamaya dayanır, bu durumda bir düğmeyi yalnızca bir kez tıklatabilirsiniz, eğer başka bir tıklama istiyorsanız açıkça belirtmeniz gerekir .

/**
 * Listener que sólo permite hacer click una vez, para poder hacer click
 * posteriormente se necesita indicar explicitamente.
 *
 * @author iberck
 */
public abstract class OnExplicitClickListener implements View.OnClickListener {

    // you can perform a click only once time
    private boolean canClick = true;

    @Override
    public synchronized void onClick(View v) {
        if (canClick) {
            canClick = false;
            onOneClick(v);
        }
    }

    public abstract void onOneClick(View v);

    public synchronized void enableClick() {
        canClick = true;
    }

    public synchronized void disableClick() {
        canClick = false;
    }
}

Kullanım örneği:

OnExplicitClickListener clickListener = new OnExplicitClickListener() {
    public void onOneClick(View v) {
        Log.d("example", "explicit click");
        ...
        clickListener.enableClick();    
    }
}
button.setOnClickListener(clickListener);

2
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {

    private final AtomicBoolean onClickEnabled = new AtomicBoolean(true);

    @Override
    public void onClick(View v) {
        Log.i("TAG", "onClick begin");
        if (!onClickEnabled.compareAndSet(true, false)) {
            Log.i("TAG", "onClick not enabled");
            return;
        }

        button.setEnabled(false);

        // your action here

        button.setEnabled(true);
        onClickEnabled.set(true);
        Log.i("TAG", "onClick end");
    }
});

Görünüm dinleyicileri her zaman tek bir iş parçacığında (ana) çağrılır, bu nedenle kullanmak AtomicBooleangerçekten yardımcı olamazdı.
WindRider

2

Bunu deneyin, çalışıyor:

mButton.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {

                mSlotLayout.setEnabled(false);

        //      do your work here

                Timer buttonTimer = new Timer();
                buttonTimer.schedule(new TimerTask() {

                    @Override
                    public void run() {

                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                mButton.setEnabled(true);
                            }
                        });
                    }
                }, 500); // delay button enable for 0.5 sec
    }
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.