【Android】防止過快點擊造成事件重複執行

點擊事件是Android開發中最常見的事件,正常情況下不會有什麽問題
但總時會有所謂的突發狀況(設備效能,使用者操作行為)
Android設備的機型多且雜(還不包含白牌設備),如果碰到運算效能較差的手機,
則有可能在點擊時造成延遲現象。碰到這種現象,用戶可能以為沒反應而再次點擊一次,
造成事件重複調用兩次的Bug。


開發的日子總是會遇到一些不錯的QA幫你測試(特別愛瘋狂亂點的那種)
剛開始會覺得很甘~  但其實RD當久了之後還真的要謝謝那些肯幫你亂點的QA
(間接的幫你練功?)
回到正題

其實稍微問一下我大哥"谷哥"就可以找到很多的文章
以下就整理幾種方法
1.自定義一個類別在onClick的時後來做限制
2.透過boolean做判定
3.利用物件本身setTag得方式來做判定(跟boolean類似)


方法一:先建立一個類別"Utils"來控制
  
public class Utils {  
    private static long lastClickTime;  
  
    public static boolean isFastDoubleClick() {  
        long time = System.currentTimeMillis();  
        long timeD = time - lastClickTime;  
        if (0 < timeD && timeD < 10000) {  
            return true;  
        }  
        lastClickTime = time;  
        return false;  
    }  
}  

在物件onClick時使用Utils來避免物件太快連續點擊
  
    button.setOnClickListener(new OnClickListener() {  
        @Override  
        public void onClick(View v) {  
            // TODO Auto-generated method stub  
            if (Utils.isFastDoubleClick()) {  
                Toast.makeText(GoogleMapActivity.this,"點太快了!", Toast.LENGTH_SHORT).show();  
                return;  
            } else {  
                Toast.makeText(GoogleMapActivity.this,"正常點擊。", Toast.LENGTH_SHORT).show();  
            }  
        }  
    });      


方法二: 透過boolean參數來控制
  
    boolean isClickTooFast = false;
    Button mButton;

    mButton.setOnClickListener(new OnClickListener() {  
        @Override  
        public void onClick(View v) {  
            // TODO Auto-generated method stub  
            if (isClickTooFast) {  
                Toast.makeText(GoogleMapActivity.this,"點太快了!", Toast.LENGTH_SHORT).show();  
            } else {  
                Toast.makeText(GoogleMapActivity.this,"正常點擊。", Toast.LENGTH_SHORT).show();
                isClickTooFast = true;
                new TimeThread.start();  
            }  
        }  
    });

    private class TimeThread extends Thread {
           public void run() {
               try {
                   sleep(1000);
                   isClickTooFast = false;
               } catch (Exception e) {
                   e.printStackTrace();
               }
           }
   }      
用這種方式的缺點,需要注意在事件結束的時間點將isClickTooFast改回false,不然會造成點擊事件失效。

方法三: 透可點擊的物件本身setTag的方式來控制
 
    Button mButton;

    mButton.setOnClickListener(new OnClickListener() {  
        @Override  
        public void onClick(View v) {  
            // TODO Auto-generated method stub  
            if (mButton.getTag() != null) {  
                Toast.makeText(GoogleMapActivity.this,"點太快了!", Toast.LENGTH_SHORT).show();  
            } else {  
                Toast.makeText(GoogleMapActivity.this,"正常點擊。", Toast.LENGTH_SHORT).show();
                mButton.setTag(true);  
            }  
        }  
    });

    private class TimeThread extends Thread {
           public void run() {
               try {
                   sleep(1000);
                   mButton.setTag(null);
               } catch (Exception e) {
                   e.printStackTrace();
               }
           }
   }      
第三種方法其實跟第二種透過boolean的方式差不多
而在boolean變回false與setTag(null)就要特別留意一下,在我們上面的範例是寫在一個TimeThread內(設定一秒)變更狀態。
比照辦理的話也可以將變更狀態的時間點寫在Call API回response的地方
延伸的變化就由各位在各自摸索啦。

沒有留言:

張貼留言