Android ngăn chặn nhấp đúp chuột vào nút


177

Cách tốt nhất để ngăn chặn nhấp đúp chuột vào một nút trong Android là gì?


3
Chỉ xem giải pháp của qezt hoàn toàn khả thi
Gennadiy Ryabkin

3
Giải pháp của qezt nên được chấp nhận, để những người truy cập trang này biết được nhược điểm của việc sử dụng setEnables (false).
LoveForDroid

Bạn có thể dùng thử thư viện của tôi, sử dụng giải pháp lần nhấp cuối cùng: github.com/RexLKW/SClick
Rex Lam

1
@Androider vui lòng thay đổi câu trả lời hay nhất của bạn
Amir133

Câu trả lời:


86

Vô hiệu hóa nút setEnabled(false)cho đến khi an toàn cho người dùng nhấp lại.


47
setEnables (false) dường như không hoạt động "nhanh". Tôi đã thiết lập một View.OnClickListener.onClick (view) cho một nút. Điều đầu tiên tôi làm trong onClick () là viết một câu lệnh log, câu lệnh thứ 2 là button.setEnables (false). Khi nhấp đúp nhanh vào trình giả lập, tôi thấy câu lệnh log xuất hiện hai lần! Ngay cả khi thêm setClickable (false) ngay sau đó, câu lệnh log vẫn xuất hiện hai lần.
QQQuestions

Hmmm, có thể mã lên đến setEnables (true) ở cuối onClick () đang được thực thi nhanh đến mức nó đã được bật lại ...
QQQuestions

91
Tôi đã có một vấn đề tương tự. Theo một quý ông hữu ích, Android thực sự xếp hàng các nhấp chuột, do đó, việc mã onClick () của bạn thực thi nhanh hay chậm; chỉ cách bạn nhấp vào nút nhanh như thế nào. I E. Bạn có thể đã tắt nút này, nhưng hàng đợi nhấp chuột đã được lấp đầy bằng hai hoặc ba lần nhấp và việc tắt nút này không ảnh hưởng gì đến việc phân phối các nhấp chuột được xếp hàng. (mặc dù có lẽ nó nên?)
Nick

3
Khoảnh khắc hiếm hoi đó khi bạn thấy 'ai đó' đưa ra câu trả lời chính xác và không trả lời chính xác cho câu hỏi đang được hỏi ..: P
Rahul

đây không phải lúc nào cũng là giải pháp đúng Nếu onClick của bạn hoạt động đắt tiền, thì nút sẽ không vô hiệu hóa đủ nhanh. Giải pháp chứng minh đầy đủ IMHO là sử dụng thời gian nhấp chuột cuối cùng, nhưng cũng vô hiệu hóa nút để tránh người dùng chạm vào nó một lần nữa nếu bạn muốn thao tác kéo dài một thời gian (chẳng hạn như đăng nhập).
Sarang

368

tiết kiệm thời gian nhấp chuột cuối cùng khi nhấp sẽ ngăn chặn vấn đề này.

I E

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
Đây là giải pháp duy nhất thực sự ngăn chặn một cú nhấp chuột. Tôi chỉ mất một giờ để thử tất cả những cái khác vì phương pháp này khá là rắc rối, nhưng không ai trong số họ có thể ngăn được một cú chạm nhanh vào góc nhìn ngoại trừ phương pháp này. Google vui lòng sửa lỗi này :)
ashishduh

6
Giải pháp này hoạt động tốt. Giải pháp này cũng hoạt động khi bạn có nhiều nút trên màn hình và bạn chỉ muốn nhấp vào một nút duy nhất.
khoảng trống

12
Điều này không hoàn toàn ngăn chặn nhấp đúp nếu bạn nhấp đúp đủ nhanh.
Lộc

4
Câu trả lời hay nhất, nên được đặt lên hàng đầu
Gennadiy Ryabkin

3
Giải pháp này phải là câu trả lời đúng ... setEnables (false) là không đủ.
heloisasim

55

Giải pháp của tôi là

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

}

Cách sử dụng tương tự như OnClickListener nhưng thay thế ghi đè lênSingleClick ():

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

1
Dễ dàng và hoàn hảo để tự động ngăn chặn chạm hai lần.
Benjamin Piette

1
Điều này không hoàn toàn ngăn chặn nhấp đúp nếu bạn nhấp đúp đủ nhanh.
Lộc

1
Giải pháp tuyệt vời. Tôi vừa thay đổi MIN_CLICK_INTERVAL = 1000;
Nizam

5
Nếu tôi bấm nút chính xác cứ sau 0,5 giây, thì không có lần nhấp nào tiếp theo của tôi có thể vượt qua vì mLastClickTime sẽ được cập nhật mỗi lần nhấp. Đề xuất của tôi sẽ là gán mLastClickTime sau khi bạn kiểm tra khoảng thời gian.
k2col

mLastClickTime = currentClickTime; nên được đặt sau if (elapsedTime <= MIN_CLICK_INTERVAL) trở lại;
Loyea

41

Vô hiệu hóa nút hoặc cài đặt không thể bấm được là không đủ nếu bạn đang thực hiện công việc chuyên sâu tính toán trong onClick () vì các sự kiện nhấp có thể được xếp hàng trước khi nút có thể bị tắt. Tôi đã viết một lớp cơ sở trừu tượng thực hiện OnClickListener mà bạn có thể ghi đè thay vào đó, nó khắc phục vấn đề này bằng cách bỏ qua mọi nhấp chuột xếp hàng:

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

Cách sử dụng giống như OnClickListener nhưng ghi đè OnOneClick () thay vào đó:

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

Cảm ơn mã. Dựa trên những gì bạn đã viết ở đây, tôi đã tạo ra một lớp tương tự ngăn chặn các lần nhấp nếu nút hoặc nó bị ẩn - thật buồn cười khi Android sẽ xếp hàng nhấp chuột ngay cả khi bạn ẩn nút ngay sau khi nhấp.
nikib3ro

1
Tôi có một giải pháp tương tự - bạn chỉ có thể sử dụng lớp này trong xml và nó sẽ bao bọc các clickListener cho bạn github.com/doridori/AndroidUtilDump/blob/master/android/src/
Dori

2
Đây là một giải pháp tốt, nhưng onClick () và reset () cần được đồng bộ hóa, nếu không, nhấp đúp vẫn có thể lẻn vào.
Tom anMoney

6
@TomanMoney, thế nào? Không phải tất cả các sự kiện nhấp xảy ra trên một luồng UI?
Ken

@Dori liên kết đã chết
naXa

36

Bạn có thể làm điều đó theo cách rất lạ mắt với Chức năng mở rộng KotlinRxBinding

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

hoặc là

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

và sau đó chỉ:

View.clickWithDebounce{ Your code }

quá
hăng hái

3
Ra mắt cho Rx sẽ không hoạt động tốt ở đây. Thay vào đó "ThrottFirst" sẽ phù hợp hơn. demo.nimius.net/debounce_thrption ở đây là ví dụ về cách chúng khác nhau. PS: và thực tế việc thực hiện clickWithDebounce của bạn là triển khai điều tiết, không phải
gỡ lỗi

13

Tôi cũng chạy trong vấn đề tương tự, tôi đã hiển thị một số máy đo thời gian và đồng hồ bấm giờ trong đó đôi khi nó được nhấp 2 lần. Tôi đã giải quyết nó bằng cách này

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

Bạn có thể thay đổi thời gian tùy theo yêu cầu của bạn. Phương pháp này làm việc cho tôi.


Đây là giải pháp thực sự, vì nó tự động kích hoạt lại nút sau khi hết thời gian. Các giải pháp khác chặn nút vĩnh viễn nếu bạn nhấp nhanh hai lần. Giải pháp này khắc phục vấn đề! Cảm ơn
Néstor

10

setEnabled(false) làm việc hoàn hảo cho tôi

Ý tưởng là tôi viết { setEnabled(true); }vào đầu và chỉ cần thực hiện nó falsetrong lần nhấp đầu tiên của nút.


9

Tôi biết đó là một câu hỏi cũ, nhưng tôi chia sẻ giải pháp tốt nhất tôi tìm thấy để giải quyết vấn đề phổ biến này

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

Và trong một tệp khác, như 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);
}

8

Giải pháp thực tế cho vấn đề này là sử dụng setEnables (false) làm mờ nút và setClickable (false) khiến cho lần nhấp thứ hai không thể nhận được tôi đã kiểm tra điều này và nó có vẻ rất hiệu quả.


7

Nếu ai đó vẫn đang tìm kiếm một câu trả lời ngắn, bạn có thể sử dụng mã dưới đây

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

Mã này sẽ đi vào bên trong if statementbất cứ khi nào người dùng nhấp vào View within 1 secondvà sau đó mã return;sẽ được bắt đầu và mã tiếp theo sẽ không bắt đầu.


2
Đây phải là câu trả lời được chấp nhận. Siêu đơn giản và nó hoạt động ngay cả khi bạn nhấp rất nhanh! Cảm ơn vì điều đó.
Geoffroy CALA

7

Cách thành ngữ Kotlin K LEANEST :

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

Sử dụng:

button.setOnSingleClickListener { ... }

6

Giải pháp của tôi là thử sử dụng một booleanbiế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);
    }
}

Và sử dụng như dưới đây:

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

CẬP NHẬT : Giải pháp Kotlin, sử dụng phần mở rộng xem

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 hoạt động tốt với Butter Knife

ClickGuard.guard(mPlayButton);

4
tách biệt linrary cho xử lý nhấp đúp vào nút? ha
Serg Burlaka

Tôi có thể sử dụng nút bên trong tùy chỉnh này không?
Ara Badalyan

@AraBadalyan bạn có ý gì khi nói 'bên trong'. Chỉ cần vượt qua nút tùy chỉnh của bạn là param cho phương thức bảo vệ. Sau đó, nút của bạn sẽ được bảo vệ khỏi nhấp đúp
thanhbinh84

Ý tôi là tôi không muốn thêm ClickGuard.guard (mPlayButton) trong tất cả các hoạt động sử dụng onclick. Tôi muốn tạo Nút phạm vi CustomButton và đặt ClickGuard bên trong CustomButton. Nhưng khi tôi thêm ClickGuard trong hàm tạo CustomButton thì nó không hoạt động.
Ara Badalyan

@AraBadalyan đúng vậy. Nó không hoạt động theo cách đó.
thanhbinh84

5

trong tình huống của tôi, tôi đã sử dụng chế độ xem nút và nó đã thực hiện các nhấp chuột quá nhanh. chỉ cần vô hiệu hóa có thể nhấp và kích hoạt lại sau vài giây ...

Về cơ bản tôi đã tạo một lớp trình bao bọc bao quanh Lượt xem của bạn trênClickListener. bạn cũng có thể đặt độ trễ tùy chỉnh nếu bạn muốn.

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

và để gọi nó đơn giản là làm điều này:

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

hoặc cung cấp sự chậm trễ của riêng bạn:

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

CẬP NHẬT: Trên đây là một chút thời trang cũ mà RxJava rất thịnh hành. như những người khác đã đề cập, trong Android, chúng ta có thể sử dụng một bộ điều tiết để làm chậm các nhấp chuột. đây là một ví dụ:

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

bạn có thể sử dụng thư viện này cho nó: 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

Bạn có thể sử dụng phương pháp này. Bằng cách sử dụng độ trễ bài, bạn có thể chăm sóc cho các sự kiện nhấp đúp.

void debounceEffectForClick (Xem chế độ xem) {

    view.setClickable(false);

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

        }
    }, 500);
}

4

Tiện ích mở rộng Kotlin cho phép mã nội tuyến ngắn gọn và thời gian chờ nhấp đúp biến

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

Sử dụng:

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

Hoặc là

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

Tuyệt vời, mọi người nên sử dụng mã này, đoạn mã hoàn toàn tốt đẹp của nó và lý do tuyệt vời tại sao mọi người nên chuyển sang kotlin.
Achmad Naufal Syafiq

Có thể đẹp hơn nếu WaitMillis chỉ được mã hóa cứng, sau đó các dấu ngoặc đơn bên ngoài có thể được loại bỏ.
WindRider

4

Mã bên dưới sẽ ngăn người dùng nhấp nhiều lần trong một phần giây và chỉ cho phép sau 3 giây.

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

Có vẻ như việc thiết lập trình nghe nhấp chuột của bạn trong onResume và loại bỏ chúng trong onPause cũng là một mẹo nhỏ.


3

Đối với tôi chỉ nhớ dấu thời gian và kiểm tra lại nó (hơn 1 giây trôi qua kể từ lần nhấp trước) đã giúp.


3

Tôi hy vọng điều này có thể giúp BẠN, đặt mã trong trình xử lý sự kiện của bạn.

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

    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

Tôi không tìm thấy bất kỳ đề xuất nào trong số các đề xuất này nếu phương thức onClick không trả về ngay lập tức. Sự kiện chạm được xếp hàng bởi Android và onClick tiếp theo chỉ được gọi sau khi kết thúc lần đầu tiên. (Vì việc này được thực hiện trên một luồng UI nên điều này thực sự bình thường.) Tôi cần sử dụng thời gian khi chức năng onClick kết thúc + một biến boolean để đánh dấu xem onClick đã cho có chạy hay không. Cả hai thuộc tính đánh dấu này đều tĩnh để tránh mọi onClickListener chạy cùng một lúc. (Nếu người dùng nhấp vào nút khác) Bạn có thể đơn giản thay thế OnClickListener của mình thành lớp này và thay vì triển khai phương thức onClick, bạn cần triển khai phương thức trừu tượng 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);
}

3

bạn cũng có thể sử dụng các ràng buộc rx bằng jake wharton để thực hiện điều này. đây là một mẫu đệm 2 giây giữa các lần nhấp liên tiếp:

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

// lưu ý: bỏ qua Object v trong trường hợp này và tôi nghĩ luôn.


3

Kotlin tạo lớp 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)
    }
}

tạo một hàm trong baseClass hoặc cách khác

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

và sử dụng trên nút bấm

btnSubmit.setSafeOnClickListener {
    showSettingsScreen()
}

1
Giải pháp sạch nhất với phần mở rộng! Cảm ơn!
android_dev



2

Cài đặt Clickable thành false không hoạt động trên lần nhấp đúp đầu tiên nhưng lần nhấp đúp tiếp theo bị chặn. Như thể lần nhấp tải đại biểu lần đầu tiên chậm hơn và lần nhấp thứ hai được bắt trước khi lần đầu tiên hoàn thành.

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

2

Tôi khắc phục vấn đề này bằng cách sử dụng hai cụm, một cụm tương tự như câu trả lời của @ jinshiyi11 và trình anoter dựa trên nhấp chuột rõ ràng, trong trường hợp này bạn chỉ có thể nhấp vào một nút một lần, nếu bạn muốn nhấp chuột khác, bạn phải chỉ ra rõ ràng .

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

Ví dụ sử dụng:

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

Người nghe xem luôn được gọi trên một chủ đề (chính) vì vậy việc sử dụng AtomicBooleankhông thực sự có ích.
WindRider

2

Hãy thử điều này, nó đang hoạt động:

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
    }
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.