Android Mencegah Klik Dua Kali Pada Tombol

177

Apa cara terbaik untuk mencegah klik dua kali pada tombol di Android?

Androider
sumber
3
Lihat solusi qezt, hanya itu sepenuhnya bisa diterapkan
Gennadiy Ryabkin
3
Solusi qezt seharusnya telah diterima, sehingga orang yang mengunjungi halaman ini, tahu kelemahan menggunakan setEnabled (false).
LoveForDroid
Anda dapat mencoba perpustakaan saya, menggunakan solusi waktu klik terakhir: github.com/RexLKW/SClick
Rex Lam
1
@Androider harap ubah jawaban terbaik Anda
Amir133

Jawaban:

86

Nonaktifkan tombol dengan setEnabled(false)sampai aman bagi pengguna untuk mengkliknya lagi.

CommonsWare
sumber
47
setEnabled (false) tampaknya tidak berfungsi "cukup" cepat. Saya telah menyiapkan sebuah View.OnClickListener.onClick (view) untuk sebuah tombol. Hal pertama yang saya lakukan di onClick () adalah menulis log-statement, pernyataan ke-2 adalah button.setEnabled (false). Ketika mengklik cepat di emulator, saya melihat log-statement muncul dua kali! Bahkan ketika menambahkan setClickable (false) tepat setelah itu, pernyataan log muncul dua kali.
QQQuestions
Hmmm, mungkin kode hingga setEnabled (true) di akhir onClick () dieksekusi sangat cepat sehingga sudah diaktifkan lagi ...
QQQuestions
91
Saya punya masalah serupa. Menurut salah satu pria yang membantu, Android sebenarnya membuat antrian klik, jadi tidak masalah seberapa cepat atau lambat kode onClick () Anda dijalankan; hanya seberapa cepat Anda mengklik tombol. Yaitu. Anda mungkin telah menonaktifkan tombol, tetapi antrian klik sudah diisi dengan dua atau tiga klik dan menonaktifkan tombol tidak berpengaruh pada pengiriman klik antrian. (walaupun mungkin harus?)
Nick
3
Saat yang langka ketika Anda melihat 'seseorang' memberikan jawaban yang tepat dan bukan abstraaaaaaaak jawaban atas pertanyaan yang diajukan ..: P
Rahul
ini tidak selalu merupakan solusi yang tepat. Jika onClick Anda adalah operasi yang mahal, maka tombol tidak akan menonaktifkan cukup cepat. Solusi bukti penuh IMHO adalah dengan menggunakan waktu klik terakhir, tetapi juga menonaktifkan tombol untuk menghindari pengguna mengetuknya lagi jika Anda mengharapkan operasi berlangsung beberapa saat (seperti login).
Sarang
368

menghemat waktu klik terakhir saat mengklik akan mencegah masalah ini.

yaitu

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
    }
}
qezt
sumber
21
Ini adalah satu-satunya solusi yang sebenarnya mencegah klik dua kali. Saya hanya menghabiskan waktu satu jam untuk mencoba yang lain karena metode ini cukup kikuk, tetapi tidak satupun dari mereka yang bisa mencegah dua kali ketukan cepat tampilan kecuali yang ini. Google tolong perbaiki ini :)
ashishduh
6
Solusi ini berfungsi dengan baik. Solusi ini juga berfungsi ketika Anda memiliki beberapa tombol di layar dan Anda hanya ingin mengklik satu tombol pada satu waktu.
batal
12
Ini tidak sepenuhnya mencegah klik dua kali jika Anda melakukan klik dua kali dengan cukup cepat.
Loc
4
Jawaban terbaik, itu harus di atas
Gennadiy Ryabkin
3
Solusi ini harus menjadi jawaban yang tepat ... setEnabled (false) tidak cukup.
heloisasim
55

Solusi saya adalah

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);        
    }

}

Penggunaannya mirip dengan OnClickListener tetapi menimpa onSingleClick () sebagai gantinya:

mTextView.setOnClickListener(new OnSingleClickListener() {
            @Override
            public void onSingleClick(View v) {
                if (DEBUG)
                    Log.i("TAG", "onclick!");
            }
     };
jinshiyi11
sumber
1
Mudah dan sempurna untuk secara otomatis mencegah sentuhan ganda.
Benjamin Piette
1
Ini tidak sepenuhnya mencegah klik dua kali jika Anda melakukan klik dua kali dengan cukup cepat.
Loc
1
Solusi bagus Saya baru saja mengubah MIN_CLICK_INTERVAL = 1000;
Nizam
5
Jika saya harus secara akurat tombol setiap 0,5 detik, tidak ada klik berikutnya saya akan melewati karena mLastClickTime akan diperbarui setiap klik. Saran saya adalah menetapkan mLastClickTime setelah Anda memeriksa interval.
k2col
mLastClickTime = currentClickTime; harus ditempatkan setelah jika (elapsedTime <= MIN_CLICK_INTERVAL) kembali;
Loyea
41

Menonaktifkan tombol atau pengaturan yang tidak dapat diklik tidak cukup jika Anda melakukan pekerjaan yang intensif secara komputasional di onClick () karena acara klik dapat menjadi antri sebelum tombol dapat dinonaktifkan. Saya menulis kelas dasar abstrak yang mengimplementasikan OnClickListener yang Anda bisa menimpanya, yang memperbaiki masalah ini dengan mengabaikan klik yang antri:

/** 
 * 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;
    }
}

Penggunaannya sama dengan OnClickListener tetapi menimpa OnOneClick () sebagai gantinya:

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);
Ken
sumber
Terima kasih untuk kodenya. Berdasarkan apa yang Anda tulis di sini, saya telah membuat kelas serupa yang mencegah klik jika tombol atau orang tuanya disembunyikan - Lucu bahwa Android akan mengantri klik bahkan jika Anda menyembunyikan tombol segera setelah klik.
nikib3ro
1
Saya punya solusi serupa - Anda bisa menggunakan kelas ini dalam xml dan itu akan membungkus clickListeners untuk Anda github.com/doridori/AndroidUtilDump/blob/master/android/src/…
Dori
2
Ini adalah solusi yang baik, tetapi onClick () dan reset () perlu disinkronkan, jika tidak klik dua kali masih bisa menyelinap masuk.
Tom anMoney
6
@TomanMoney, bagaimana? Tidak semua peristiwa klik terjadi pada utas UI tunggal?
Ken
@Dori tautannya sudah mati
naXa
36

Anda dapat melakukannya dengan sangat mewah dengan Fungsi Ekstensi Kotlin dan RxBinding

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

atau

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()
        }
    })
}

dan kemudian:

View.clickWithDebounce{ Your code }
Yvgen
sumber
over engenering
Serg Burlaka
3
Debounce untuk Rx tidak akan berfungsi dengan baik di sini. Sebaliknya "ThrottleFirst" harus lebih pas. demo.nimius.net/debounce_throttle di sini adalah contoh perbedaannya. PS: dan sebenarnya implementasi clickWithDebounce Anda adalah implementasi throttle, bukan debounce
krossovochkin
13

Saya juga menjalankan dalam masalah yang sama, saya menampilkan beberapa datepicker & timepickers di mana kadang-kadang mendapat klik 2 kali. Saya telah menyelesaikannya dengan ini

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);
}

Anda dapat mengubah waktu tergantung pada kebutuhan Anda. Metode ini bekerja untuk saya.

Mudassar
sumber
Ini adalah solusi nyata, karena itu mengaktifkan kembali tombol secara otomatis setelah waktu berlalu. Solusi lain memblokir tombol secara permanen jika Anda mengklik dua kali dengan cepat. Solusi ini memperbaiki masalah! Terima kasih
Néstor
10

setEnabled(false) bekerja dengan baik untuk saya.

Idenya adalah saya menulis { setEnabled(true); }di awal dan membuatnya falsedi klik pertama tombol.

saurabh
sumber
9

Saya tahu ini adalah pertanyaan lama, tetapi saya membagikan solusi terbaik yang saya temukan untuk menyelesaikan masalah umum ini

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

Dan di file lain, seperti Utils.java

    /**
 * 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);
}
Gustavo
sumber
8

Solusi aktual untuk masalah ini adalah dengan menggunakan setEnabled (false) yang menghilangkan tombol, dan setClickable (false) yang membuatnya jadi klik kedua tidak dapat diterima. Saya telah menguji ini dan tampaknya sangat efektif.

EpicOfChaos
sumber
7

Jika seseorang masih mencari jawaban singkat, Anda dapat menggunakan kode di bawah ini

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

Kode ini akan masuk ke dalam if statementsetiap kali pengguna mengklik View within 1 seconddan kemudian return;akan dimulai dan kode lebih lanjut tidak akan memulai.

Rakshit Nawani
sumber
2
Ini harus menjadi jawaban yang diterima. Sangat sederhana dan berfungsi bahkan jika Anda mengklik sangat cepat! Terima kasih untuk ini.
Geoffroy CALA
7

Cara idiomatis K TERTINGGI Kotlin :

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))
}

Pemakaian:

button.setOnSingleClickListener { ... }
Penunggang Angin
sumber
6

Solusi saya adalah mencoba menggunakan booleanvariabel:

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);
    }
}

Dan menggunakan seperti di bawah ini:

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   
                }
            }
        });

PEMBARUAN : Solusi Kotlin, menggunakan ekstensi tampilan

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)
    }
}
GianhTran
sumber
5

Click Guard bekerja dengan baik dengan Butter Knife

ClickGuard.guard(mPlayButton);
thanhbinh84
sumber
4
terpisah secara terpisah untuk menangani klik dua kali pada tombol? ha
Serg Burlaka
Bisakah saya menggunakan ini di dalam tombol kustom?
Ara Badalyan
@AraBadalyan apa yang Anda maksud dengan 'inside'. Cukup lewati tombol kustom Anda sebagai param untuk metode penjaga. Maka tombol Anda akan terlindung dari klik dua kali
thanhbinh84
Maksud saya, saya tidak ingin menambahkan ClickGuard.guard (mPlayButton) di semua aktivitas yang menggunakan onclick. Saya ingin membuat Tombol Sejauh CustomButton dan memasukkan ClickGuard ke dalam CustomButton. Tetapi ketika saya menambahkan ClickGuard di konstruktor CustomButton itu tidak berhasil.
Ara Badalyan
@AraBadalyan itu benar. Tidak berfungsi seperti itu.
thanhbinh84
5

dalam situasi saya, saya menggunakan tampilan tombol dan itu mengambil klik terlalu cepat. cukup nonaktifkan yang dapat diklik dan aktifkan lagi setelah beberapa detik ...

Pada dasarnya saya membuat kelas pembungkus yang membungkus Views onClickListener Anda. Anda juga dapat mengatur penundaan khusus jika Anda mau.

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);
        }
    }

dan untuk menyebutnya cukup lakukan ini:

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

atau berikan penundaan Anda sendiri:

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

UPDATE: Di atas cara mode lama sedikit sekarang bahwa RxJava sangat lazim. seperti yang orang lain katakan, di android kita bisa menggunakan throttle untuk memperlambat klik. di sini adalah satu contoh:

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

Anda dapat menggunakan perpustakaan ini untuk itu: implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'

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

Anda dapat menggunakan metode ini. Dengan menggunakan post delay Anda dapat menangani acara klik ganda.

batal debounceEffectForClick (Tampilan tampilan) {

    view.setClickable(false);

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

        }
    }, 500);
}
manmohan
sumber
4

Ekstensi Kotlin yang memungkinkan kode inline singkat & waktu tunggu klik ganda variabel

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()
        }
    }
}

Pemakaian:

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

Atau

anyView.setNoDoubleClickListener(View.OnClickListener { v ->
    // do stuff
}, 1500)
Jim
sumber
Luar biasa, semua orang harus menggunakan ini, kode yang benar-benar bagus dan alasan bagus mengapa semua orang harus bermigrasi ke kotlin.
Achmad Naufal Syafiq
Bisa lebih baik jika waitMillis hanya dikodekan, maka tanda kurung luar dapat dihilangkan.
WindRider
4

Kode di bawah ini akan mencegah pengguna mengklik beberapa kali dalam sepersekian detik dan hanya mengizinkan setelah 3 detik.

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();
    }
}
Milan Sheth
sumber
3

Tampaknya menyetel pendengar klik Anda di onResume dan menghapusnya di onPause juga berfungsi.

khendricks
sumber
3

Bagi saya hanya mengingat cap waktu dan mengeceknya (yang lebih dari 1 detik berlalu sejak klik sebelumnya) membantu.

shtolik
sumber
3

Saya harap ini dapat membantu ANDA, memasukkan kode Anda event handler.

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

    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 );
    }
ONG
sumber
3

Saya menemukan tidak ada saran ini yang berfungsi jika metode onClick tidak segera kembali. Acara sentuh antri oleh Android dan onClick berikutnya dipanggil hanya setelah yang pertama selesai. (Karena ini dilakukan pada satu UI thread ini benar-benar normal.) Saya perlu menggunakan waktu ketika fungsi onClick selesai + satu variabel boolean untuk menandai apakah onClick yang diberikan sedang berjalan. Kedua atribut marker ini bersifat statis untuk menghindari onClickListener untuk berjalan secara bersamaan. (Jika pengguna mengklik tombol lain) Anda dapat dengan mudah mengganti OnClickListener Anda ke kelas ini dan alih-alih menerapkan metode onClick Anda perlu menerapkan metode abstrak oneClick ().

    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);
}
linczy
sumber
3

Anda juga dapat menggunakan rx bindings dengan jake wharton untuk mencapai ini. berikut adalah contoh yang mengisi 2 detik antara klik berurutan:

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
                });

// note: abaikan Object v dalam hal ini dan saya pikir selalu.

j2emanue
sumber
3

Kotlin membuat kelas SafeClickListener

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)
    }
}

buat fungsi di baseClass atau yang lain

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

dan gunakan pada klik tombol

btnSubmit.setSafeOnClickListener {
    showSettingsScreen()
}
jai khambhayta
sumber
1
Solusi terbersih dengan ekstensi! Terima kasih!
android_dev
3

Di kotlin

button.setOnClickListener { 
    it?.apply { isEnabled = false; postDelayed({ isEnabled = true }, 400) } //400 ms
    //do your work
}
Владислав Прасков
sumber
2

Pengaturan Clickable to false tidak berfungsi pada klik ganda pertama tetapi klik ganda berikutnya diblokir. Seolah-olah delegasi klik pemuatan pertama kali lebih lambat dan klik kedua ditangkap sebelum yang pertama selesai.

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

Saya memperbaiki masalah ini menggunakan dua klausa, satu mirip dengan jawaban @ jinshiyi11 dan anoter didasarkan pada klik eksplisit, dalam hal ini Anda dapat mengklik tombol hanya sekali saja, jika Anda ingin klik lain Anda harus menunjukkannya secara eksplisit .

/**
 * 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;
    }
}

Contoh penggunaan:

OnExplicitClickListener clickListener = new OnExplicitClickListener() {
    public void onOneClick(View v) {
        Log.d("example", "explicit click");
        ...
        clickListener.enableClick();    
    }
}
button.setOnClickListener(clickListener);
iberck
sumber
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");
    }
});
Milan Hlinák
sumber
Lihat pendengar selalu dipanggil di utas tunggal (utama) sehingga menggunakan AtomicBooleantidak bisa membantu.
WindRider
2

Coba ini, ini berfungsi:

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
    }
});
Raja Misa
sumber