Skip to content

Instantly share code, notes, and snippets.

@nvanbenschoten
Last active August 29, 2015 13:57
Show Gist options
  • Save nvanbenschoten/9919332 to your computer and use it in GitHub Desktop.
Save nvanbenschoten/9919332 to your computer and use it in GitHub Desktop.
An Android utility class handling successive clicks in a given amount of time. Useful for easter eggs or extending default click behavior to more complicated situations.
/**
* Util class handling successive clicks in a given amount of time.
* Useful for easter eggs or extending default click behavior to more
* complicated situations.
*
* Created by Nathan VanBenschoten on 4/1/2014.
* Copyright (c) 2014 Tablelist LLC. All rights reserved.
*/
public class SuccessiveClickUtil {
/**
* Internal class holding a click count and a handler.
*/
private class ClickHandler {
/**
* The number of clicks performed on this handler.
*/
int mClicks;
/**
* A handler to perform countdown and removal operations.
*/
Handler mHandler;
}
/**
* This minimum number of clicks needed to execute the OnClickLimitReached callback.
*/
private final int mMinimumClicks;
/**
* The maximum period each ClickHandler has to reach it's needed number of clicks.
*/
private final long mPeriodMillis;
/**
* Listener used to dispatch click limit reached events.
*/
private OnClickLimitReached mOnClickLimitReached;
/**
* A HashSet holding all living instances of ClickHandlers.
*/
private HashSet<ClickHandler> mClickHandlers;
/**
* Basic constructor used to instantiate a SuccessiveClickUtil
*
* @param minimumClicks The minimum number of clicks needed to execute the
* OnClickLimitReached callback.
* @param periodMillis The period these clicks need to be performed within,
* or <= 0 for no time limit.
*/
public SuccessiveClickUtil(int minimumClicks, long periodMillis) {
this.mMinimumClicks = minimumClicks;
if (periodMillis <= 0) periodMillis = Long.MAX_VALUE;
this.mPeriodMillis = periodMillis;
this.mClickHandlers = new HashSet<ClickHandler>();
}
/**
* Register a callback to be invoked when a ClickHandler's limit is reached.
*
* @param onClickLimitReached The callback that will run.
*/
public void setOnClickLimitReached(OnClickLimitReached onClickLimitReached) {
mOnClickLimitReached = onClickLimitReached;
}
/**
* Increment all ClickHandler's of a 'click', checking to make sure none have reached
* their limit. If not, create a new ClickHandler starting with this click.
*/
public void performClick() {
// Increment each ClickHandler's click count and check for reached limits
for (ClickHandler handler : mClickHandlers) {
handler.mClicks++;
if (handler.mClicks >= mMinimumClicks) {
if (mOnClickLimitReached != null)
mOnClickLimitReached.onLimitReached();
mClickHandlers.clear();
return;
}
}
// Create a new ClickHandler and add it to the click handler set
final ClickHandler newHandler = new ClickHandler();
newHandler.mClicks++;
newHandler.mHandler = new Handler();
newHandler.mHandler.postDelayed(new Runnable() {
@Override
public void run() {
// Delete handler if time limit is reached
mClickHandlers.remove(newHandler);
}
}, mPeriodMillis);
mClickHandlers.add(newHandler);
}
/**
* Interface definition for a callback to be invoked when a click limit is reached.
*/
public interface OnClickLimitReached {
/**
* Called when a click limit has been reached.
*/
void onLimitReached();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment