Last active
November 14, 2023 10:49
-
-
Save nomanr/d142f4ccaf55ceba22e7f7122b55b9b6 to your computer and use it in GitHub Desktop.
A simple Android class that can start continuous counter when pressed and hold on a view.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package noman.counterhelper; | |
import android.os.Bundle; | |
import android.support.v7.app.AppCompatActivity; | |
import android.view.View; | |
import android.widget.Button; | |
import android.widget.TextView; | |
/** | |
* Created by Noman on 11/8/2016. | |
*/ | |
public class CounterExampleActivity extends AppCompatActivity implements CounterHandler.CounterListener{ | |
TextView txtCounter; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_counter_example); | |
Button buttonPlus = (Button) findViewById(R.id.buttonPlus); | |
Button buttonMinus = (Button) findViewById(R.id.buttonMinus); | |
txtCounter = (TextView) findViewById(R.id.txtCounter); | |
new CounterHandler.Builder() | |
.incrementalView(buttonPlus) | |
.decrementalView(buttonMinus) | |
.minRange(-50) // cant go any less than -50 | |
.maxRange(50) // cant go any further than 50 | |
.isCycle(true) // 49,50,-50,-49 and so on | |
.counterDelay(200) // speed of counter | |
.counterStep(2) // steps e.g. 0,2,4,6... | |
.listener(this) // to listen counter results and show them in app | |
.build(); | |
} | |
@Override | |
public void onIncrement(View view, long number) { | |
txtCounter.setText(String.valueOf(number)); | |
} | |
@Override | |
public void onDecrement(View view, long number) { | |
txtCounter.setText(String.valueOf(number)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package noman.counterhelper; | |
import android.os.Handler; | |
import android.view.MotionEvent; | |
import android.view.View; | |
/** | |
* Created by Noman on 11/8/2016. | |
*/ | |
public class CounterHandler { | |
final Handler handler = new Handler(); | |
private View incrementalView; | |
private View decrementalView; | |
private long minRange = -1; | |
private long maxRange = -1; | |
private long startNumber = 0; | |
private long counterStep = 1; | |
private int counterDelay = 50; //millis | |
private boolean isCycle = false; | |
private boolean autoIncrement = false; | |
private boolean autoDecrement = false; | |
private CounterListener listener; | |
private Runnable counterRunnable = new Runnable() { | |
@Override | |
public void run() { | |
if (autoIncrement) { | |
increment(); | |
handler.postDelayed(this, counterDelay); | |
} else if (autoDecrement) { | |
decrement(); | |
handler.postDelayed(this, counterDelay); | |
} | |
} | |
}; | |
private CounterHandler(Builder builder) { | |
incrementalView = builder.incrementalView; | |
decrementalView = builder.decrementalView; | |
minRange = builder.minRange; | |
maxRange = builder.maxRange; | |
startNumber = builder.startNumber; | |
counterStep = builder.counterStep; | |
counterDelay = builder.counterDelay; | |
isCycle = builder.isCycle; | |
listener = builder.listener; | |
initDecrementalView(); | |
initIncrementalView(); | |
if (listener != null) { | |
listener.onIncrement(incrementalView, startNumber); | |
listener.onDecrement(decrementalView, startNumber); | |
} | |
} | |
private void initIncrementalView() { | |
incrementalView.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
increment(); | |
} | |
}); | |
incrementalView.setOnLongClickListener(new View.OnLongClickListener() { | |
@Override | |
public boolean onLongClick(View v) { | |
autoIncrement = true; | |
handler.postDelayed(counterRunnable, counterDelay); | |
return false; | |
} | |
}); | |
incrementalView.setOnTouchListener(new View.OnTouchListener() { | |
@Override | |
public boolean onTouch(View v, MotionEvent event) { | |
if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement) { | |
autoIncrement = false; | |
} | |
return false; | |
} | |
}); | |
} | |
private void initDecrementalView() { | |
decrementalView.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
decrement(); | |
} | |
}); | |
decrementalView.setOnLongClickListener(new View.OnLongClickListener() { | |
@Override | |
public boolean onLongClick(View v) { | |
autoDecrement = true; | |
handler.postDelayed(counterRunnable, counterDelay); | |
return false; | |
} | |
}); | |
decrementalView.setOnTouchListener(new View.OnTouchListener() { | |
@Override | |
public boolean onTouch(View v, MotionEvent event) { | |
if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) { | |
autoDecrement = false; | |
} | |
return false; | |
} | |
}); | |
} | |
private void increment() { | |
long number = startNumber; | |
if (maxRange != -1) { | |
if (number + counterStep <= maxRange) { | |
number += counterStep; | |
} else if (isCycle) { | |
number = minRange == -1 ? 0 : minRange; | |
} | |
} else { | |
number += counterStep; | |
} | |
if (number != startNumber && listener != null) { | |
startNumber = number; | |
listener.onIncrement(incrementalView, startNumber); | |
} | |
} | |
private void decrement() { | |
long number = startNumber; | |
if (minRange != -1) { | |
if (number - counterStep >= minRange) { | |
number -= counterStep; | |
} else if (isCycle) { | |
number = maxRange == -1 ? 0 : maxRange; | |
} | |
} else { | |
number -= counterStep; | |
} | |
if (number != startNumber && listener != null) { | |
startNumber = number; | |
listener.onDecrement(decrementalView, startNumber); | |
} | |
} | |
public interface CounterListener { | |
void onIncrement(View view, long number); | |
void onDecrement(View view, long number); | |
} | |
public static final class Builder { | |
private View incrementalView; | |
private View decrementalView; | |
private long minRange=-1; | |
private long maxRange=-1; | |
private long startNumber=0; | |
private long counterStep =1; | |
private int counterDelay=50; | |
private boolean isCycle; | |
private CounterListener listener; | |
public Builder() { | |
} | |
public Builder incrementalView(View val) { | |
incrementalView = val; | |
return this; | |
} | |
public Builder decrementalView(View val) { | |
decrementalView = val; | |
return this; | |
} | |
public Builder minRange(long val) { | |
minRange = val; | |
return this; | |
} | |
public Builder maxRange(long val) { | |
maxRange = val; | |
return this; | |
} | |
public Builder startNumber(long val) { | |
startNumber = val; | |
return this; | |
} | |
public Builder counterStep(long val) { | |
counterStep = val; | |
return this; | |
} | |
public Builder counterDelay(int val) { | |
counterDelay = val; | |
return this; | |
} | |
public Builder isCycle(boolean val) { | |
isCycle = val; | |
return this; | |
} | |
public Builder listener(CounterListener val) { | |
listener = val; | |
return this; | |
} | |
public CounterHandler build() { | |
return new CounterHandler(this); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
nice work.