防止重複點擊工具類 SingleClickUtils

臨時想到的防止重複點擊工具類,備忘java

SingleClickUtils:

package ***;

import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;

import java.lang.ref.WeakReference;
import java.util.HashMap;

public final class SingleClickUtils {
    private static final String TAG = "SingleClickUtils";
    private static final long maxClickPeriod = 30L;
    private static HashMap<SuperWeakReference, Long> map = new HashMap<SuperWeakReference, Long>();

    private SingleClickUtils() {
        throw new RuntimeException("you shouldn't create SingleClickUtils instance via this private constructor");
    }
    public static void setViewSingleClick(@NonNull SingleClickListener clickListener, View... targets) {
        if (targets != null && targets.length > 0) {
            for (View target : targets) {
                setViewSingleClick(target, maxClickPeriod, clickListener);
            }
        }
    }
    public static void setViewSingleClick(@NonNull SingleClickListener clickListener, long maxClickPeriod, View... targets) {
        if (targets != null && targets.length > 0 && maxClickPeriod > 0) {
            for (View target : targets) {
                setViewSingleClick(target, maxClickPeriod, clickListener);
            }
        }
    }
    public static void setViewSingleClick(final View target, final long maxClickPeriod, @NonNull final SingleClickListener clickListener) {
        SuperWeakReference reference = new SuperWeakReference(target);
        map.put(reference, -1L);
        target.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG,"setOnClickListener onClick id:"+target.getId()+";start");
                SuperWeakReference reference = new SuperWeakReference(target);
                if (map.get(reference) == null) {
                    Log.d(TAG,"setOnClickListener onClick start id:"+target.getId()+";return null");
                    return;
                }
                Long targetLastClickTimeStamp = map.get(reference);
                if (targetLastClickTimeStamp <= 0) {
                    Log.d(TAG,"setOnClickListener onClick start id:"+target.getId()+";execute laseClickTimeStamp<0");
                    map.put(reference, SystemClock.elapsedRealtime());
                    clickListener.onClick(target);
                    return;
                }
                long currTimeStamp = SystemClock.elapsedRealtime();
                long duration = currTimeStamp - targetLastClickTimeStamp;
                if (duration <= maxClickPeriod) {
                    Log.d(TAG,"setOnClickListener onClick start id:"+target.getId()+";return click too often.duration:"+(currTimeStamp - targetLastClickTimeStamp)+"ms");
                    clickListener.clickTooOften(target);
                    return;
                } else {
                    Log.d(TAG,"setOnClickListener onClick start id:"+target.getId()+";execute >maxClickPeriod");
                    map.put(reference, currTimeStamp);
                    clickListener.onClick(target);
                    return;
                }
            }
        });
    }
    public static void removeSingleClick(View... targets){
        Log.d(TAG,"removeSingleClick start mapSize:"+map.size());
        if (targets != null && targets.length > 0 && maxClickPeriod > 0) {
            for (View target : targets) {
                map.remove(new SuperWeakReference(target));
            }
        }
        Log.d(TAG,"removeSingleClick end mapSize:"+map.size());
    }
    static class SuperWeakReference extends WeakReference<View> {
        private View currView;

        public SuperWeakReference(View referent) {
            super(referent);
            this.currView = referent;
        }
        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            } else if (obj == null) {
                return false;
            } else if (!(obj instanceof SuperWeakReference)) {
                return false;
            } else {
                SuperWeakReference ori = (SuperWeakReference) obj;
                return ori.get() != null && ori.get() == currView;
            }
        }
        @Override
        public int hashCode() {
            return (int) (currView == null ? -1L : currView.getId());
        }
    }
    public interface SingleClickListener {
        void onClick(View v);
        void clickTooOften(View v);
    }
}
複製代碼

在Activity中使用SingleClickUtils

//在Activity中使用
//Activity實現SingleClickUtils.SingleClickListener.
//固然也能夠爲每一個View單獨設置不一樣的SingleClickListener.
public class TestAvoidClickTooOftenActivity extends AppCompatActivity implements SingleClickUtils.SingleClickListener {
    private Button bt1, bt2, bt3, bt4;
    ****
    private void initViews() {
        bt1 = findViewById(R.id.bt1);
        bt2 = findViewById(R.id.bt2);
        bt3 = findViewById(R.id.bt3);
        bt4 = findViewById(R.id.bt4);
        //爲bt1, bt2, bt3設置防止重複/頻繁點擊監聽,並設置時間間隔爲300ms
        SingleClickUtils.setViewSingleClick(this, 300, bt1, bt2, bt3);
        //bt4點擊後,移除bt1, bt2, bt3的重複/頻繁點擊監聽
        bt4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SingleClickUtils.removeSingleClick(bt1,bt2,bt3);
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            //在Activity的onDestroy中移除監聽,儘早釋放內存
            SingleClickUtils.removeSingleClick(bt1,bt2,bt3);
        } catch (Exception e) {
            Log.e(TAG,"removeSingleClick err:"+e.getMessage());
            e.printStackTrace();
        }
    }
    private static final String TAG = "SingleClickUtils";
    //經檢測非頻繁點擊,可繼續執行點擊邏輯回調
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt1:
                Log.d(TAG,"R.id.bt1 too often!no");
                break;
            case R.id.bt2:
                Log.d(TAG,"R.id.bt2 too often!no");
                break;
            case R.id.bt3:
                Log.d(TAG,"R.id.bt3 too often!no");
                break;
            default:
                break;
        }
    }
    //經檢測爲頻繁點擊,自定義指定View的處理邏輯
    @Override
    public void clickTooOften(View v) {
        switch (v.getId()) {
            case R.id.bt1:
                Log.d(TAG,"R.id.bt1 too often!");
                break;
            case R.id.bt2:
                Log.d(TAG,"R.id.bt2 too often!");
                break;
            case R.id.bt3:
                Log.d(TAG,"R.id.bt3 too often!");
                break;
            default:
                break;
        }
    }
複製代碼
相關文章
相關標籤/搜索