臨時想到的防止重複點擊工具類,備忘java
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中使用
//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;
}
}
複製代碼