Starting chronometer with reDraw - android

Hi I am working on an android application which involves redrawing of the canvas and starting of chronometer at the same time. Anybody knows how can this be achieved?
I have tried to call chronometer.start in View class when invalidate() is called. However, only the canvas is redrawn and the chronometer did not start at all.
EDIT:
Here's the code I tried:
public class ReDraw extends View{
public ReDraw(Context context){
super(context);
this.selfPointer = this;
setFocusable(true);
chrono(context);
}
public void chrono(Context context){
chrono = new Chronometer(context);
chrono.setOnChronometerTickListener(new OnChronometerTickListener(){
public void onChronometerTick(Chronometer arg){
elapsedTime = (SystemClock.elapsedRealtime() - arg.getBase()) / 1000;
long milliseconds= (long) (elapsedTime/60);
String millisec=Long.toString(milliseconds);
arg.setText(millisec);
}
});
chrono.setBase(SystemClock.elapsedRealtime());
chrono.start();
}
}
protected void onDraw(Canvas Square)
{
super.onDraw(Square);
Paint squareColor = new Paint();
squareColor.setColor(Color.BLACK);
Square.drawRect(200,100,200,100, squareColor);
return;
}
}
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
invalidate();
}
return;
}
}

Your invalidate() method will only call onDraw() method not the constructor of the ReDraw.
That's why u only the canvas is redrawn.
try chrono.start() after drawing the square
i.e.
Square.drawRect(200,100,200,100, squareColor);
chrono.start()
UPDATE
try this
public class ReDraw extends View{
String currentTime="00:00:00";
public ReDraw(Context context){
super(context);
this.selfPointer = this;
setFocusable(true);
chrono(context);
}
public void chrono(Context context){
chrono = new Chronometer(context);
chrono.setOnChronometerTickListener(new OnChronometerTickListener(){
public void onChronometerTick(Chronometer arg){
String HH =((elapsedTime / 3600) < 10 ? "0" : "") + (elapsedTime / 3600);
String MM =((elapsedTime / 60) < 10 ? "0" : "") + (elapsedTime / 60);
String SS =((elapsedTime % 60) < 10 ? "0" : "") + (elapsedTime % 60);
currentTime = HH+":"+MM+":"+SS;
elapsedTime = (SystemClock.elapsedRealtime() - arg.getBase()) / 1000;
arg.setText(currentTime);
}
});
chrono.setBase(SystemClock.elapsedRealtime());
chrono.start();
}
}
protected void onDraw(Canvas Square)
{
super.onDraw(Square);
Paint squareColor = new Paint();
squareColor.setColor(Color.BLACK);
Square.drawRect(200,100,200,100, squareColor);
return;
}
}
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
chrono.start();
}
return true;
}
}

Related

Android: Surface has been released

So this bit of code seems to be the problem:
public void surfaceCreated(final SurfaceHolder sh) {
loop = new Loop();
loop.setMethod(new LoopMethod() {
public void callMethod() {
Canvas canvas = sh.lockCanvas();
synchronized(sh) {
draw(canvas);
}
sh.unlockCanvasAndPost(canvas);
}
});
loop.setRunning(true);
loop.start();
}
This works fine up until the user backs out of the application, or opens up the Recent Items tray. Upon which I get the following error:
java.lang.IllegalStateException: Surface has already been released.
which points to this line:
sh.unlockCanvasAndPost(canvas);
Why is this occurring and how do I fix it?
EDIT: ENTIRE PROBLEMATIC CLASS
public class SplashScreen extends SurfaceView implements SurfaceHolder.Callback {
private SplashActivity splashActivity;
private Loop loop;
//Loading gif info
private Movie loadingGif;
private long gifStart;
private int gifW, gifH;
private boolean gifDone;
public SplashScreen(Context context, SplashActivity splashActivity) {
super(context);
getHolder().addCallback(this);
this.splashActivity = splashActivity;
//Load gif in
InputStream gifStream = context.getResources().openRawResource(+ R.drawable.load);
loadingGif = Movie.decodeStream(gifStream);
gifW = loadingGif.width();
gifH = loadingGif.height();
gifDone = false;
}
private void beginLoading() {
}
public void surfaceCreated(final SurfaceHolder sh) {
loop = new Loop();
loop.setMethod(new LoopMethod() {
public void callMethod() {
Canvas canvas = sh.lockCanvas();
synchronized(sh) {
draw(canvas);
}
sh.unlockCanvasAndPost(canvas);
}
});
loop.setRunning(true);
loop.start();
}
public void draw(Canvas canvas) {
if(canvas != null) {
super.draw(canvas);
canvas.save();
canvas.drawColor(Color.rgb(69, 69, 69));
Paint p = new Paint();
p.setAntiAlias(true);
long now = android.os.SystemClock.uptimeMillis();
if(gifStart == 0)
gifStart = now;
if(loadingGif != null) {
int dur = loadingGif.duration();
if(!gifDone) {
int relTime = (int) ((now - gifStart) % dur);
loadingGif.setTime(relTime);
}
else
loadingGif.setTime(dur);
if(now - gifStart > dur && !gifDone) {
gifDone = true;
loadingGif.setTime(dur);
beginLoading();
}
float scaleX = getWidth()/gifW*1f;
float scaleY = getHeight()/gifH*1f;
float centerX = getWidth()/2/scaleX - gifW/2;
float centerY = getHeight()/2/scaleY - gifH/2;
canvas.scale(scaleX, scaleY);
loadingGif.draw(canvas, centerX, centerY, p);
canvas.restore();
p.setColor(Color.WHITE);
p.setTypeface(Typeface.create("Segoe UI", Typeface.BOLD));
p.setTextSize(UsefulMethods.spToPx(12));
String s = "Version " + BuildConfig.VERSION_NAME;
canvas.drawText(s, 10, getHeight() - 10, p);
}
}
else
System.out.println("not drawing :(");
}
public void surfaceDestroyed(SurfaceHolder sh) {
loop.setRunning(false);
}
public void surfaceChanged(SurfaceHolder sh, int format, int width, int height) {
System.out.println("call");
}
}
Check if visibility has changed, if it has pause/resume loop:
public void onVisibilityChanged(View view, int visibility) {
super.onVisibilityChanged(view, visibility);
if(loop != null)
if(visibility == VISIBLE)
if(!loop.isRunning())
loop.setRunning(true);
else;
else if(visibility == INVISIBLE)
if(loop.isRunning())
loop.setRunning(false);
}
In my case I covered sh.unlockCanvasAndPost with
if(sh.getSurface().isValid()){
sh.unlockCanvasAndPost(canvas);
}
If we will check isValid() source will see:
Returns true if this object holds a valid surface.
#return True if it holds a physical surface, so lockCanvas() will succeed.Otherwise returns false.

Android app crashes upon attempt to switch to a different Activity

I am running into an issue in my app. When my game ends (when life == 0) I am attempting to switch to a game over screen by using a different activity. When the game ends, the app simply crashes. I have included the XML for the activity I am trying to switch from as well as indicating where the app crashes. If anyone could help out, that would be great! Thanks.
activity_game.XML:
SurfaceView I am trying to switch from once game ends:
public class SVGameView extends SurfaceView implements Runnable {
private SurfaceHolder holder;
Thread thread = null;
volatile boolean running = false;
static final long FPS = 30;
private Sprite sprite;
private long lastClick;
private Bitmap ball, gameOver;
//private int x = 200, y = 200;
private int scorePosX = 100;
private int scorePosY = 100;
private int countScore = 0;
private int life = 1;
public SVGameView(Context context) {
super(context);
thread = new Thread(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
running = false;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
running = true;
thread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball2);
gameOver = BitmapFactory.decodeResource(getResources(),R.drawable.endscreen);
sprite = new Sprite(this, ball);
}
#Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = getHolder().lockCanvas();
synchronized (getHolder()) {
update();
draw(c);
}
} finally {
if (c != null) {
getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
thread.sleep(sleepTime);
else
thread.sleep(10);
} catch (Exception e) {}
}
}
private void update(){
sprite.update();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
Paint paint = new Paint();
canvas.drawPaint(paint);
paint.setColor(Color.WHITE);
paint.setTextSize(48);
canvas.drawText("Score: " + countScore, scorePosX, scorePosY, paint);
canvas.drawText("Lives: " + life, 500, 100, paint);
sprite.onDraw(canvas);
//Crashes here
if(life == 0) {
getContext().startActivity(new Intent(getContext(), SVGameOver.class));
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(System.currentTimeMillis()-lastClick > 300){
lastClick = System.currentTimeMillis();
}
synchronized (getHolder()){
if(sprite.isHit(event.getX(), event.getY())){
countScore += 1;
sprite.increase();
}else{
life --;
}
}
return super.onTouchEvent(event);
}
}
Activity I am trying to reach once the game ends:
public class SVGameOver extends Activity {
private Bitmap gameOverScreen;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
gameOverScreen = BitmapFactory.decodeResource(getResources(), R.drawable.endscreen);
}
protected void onDraw(Canvas canvas){
canvas.drawBitmap(gameOverScreen, 0,0,null);
}
}
I think logcat is asking you the right question: "have you declared this activity in your AndroidManifest.xml" ?
If you think you did it, It's highly probable you did it in a wrong way, most of the times that you think you added an Activity to the manifest but you are receiving this kind of crash, 99,9% of the time you declared it with a wrong namespace
Declare SVGameOver activity in your AndroidManifest.xml:
<activity
android:name="com.example.welcome.assignment2.SVGameOver">
...
</activity>

How to slow down an animation in its middle while being executed?

As the question is clearly stated, I want to slow down a TranslateAnimation while it is being executed when a user clicks on a certain button.
This is how I instantiate the TranslateAnim where -textViewHeight and layoutHeight are just some values I already instantiated in earlier time:
It goes from up to bottom.
TranslateAnim translateAnim = new TranslateAnim(0, 0, -textViewHeight, layoutHeight);
translateAnim.setDuration(20000);
translateAnim.setInterpolator(new LinearInterpolator());
textView.startAnimation(translateAnim);
This is the method where I want to slow the TranslateAnim down:
It didn't work as I expected though.
public void slowDown() {
translateAnim.setStartTime(translateAnim.getStartTime() - 20000);
translateAnim.setDuration((20000 - translateAnim.getElapsedTime()) * 2);
}
I also tried doing that but still no luck:
translateAnim.setInterpolator(new DecelerateInterpolator());
My custom TranslateAnim class extending TranslateAnimation:
public class TranslateAnim extends TranslateAnimation {
private long mElapsedAtPause, elapsedTime;
private boolean mPaused = false;
public TranslateAnim(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
super(fromXDelta, toXDelta, fromYDelta, toYDelta);
}
#Override
public boolean getTransformation(long currentTime, Transformation outTransformation) {
if (mPaused && mElapsedAtPause == 0) {
mElapsedAtPause = currentTime - getStartTime();
}
if (mPaused) {
setStartTime(currentTime - mElapsedAtPause);
}
elapsedTime = currentTime - getStartTime();
return super.getTransformation(currentTime, outTransformation);
}
public long getElapsedTime() {
return elapsedTime;
}
public void slowDown() {
translateAnim.setStartTime(translateAnim.getStartTime() - 20000);
translateAnim.setDuration((20000 - translateAnim.getElapsedTime()) * 2);
}
public void pause() {
mElapsedAtPause = 0;
mPaused = true;
}
public void resume() {
mPaused = false;
}
#Override
public void cancel() {
super.cancel();
elapsedTime = 0;
mElapsedAtPause = 0;
mPaused = false;
}
}
Is there any workaround for this?
Use a custom Interpolator instead of a linear one. A linear one causes it to have equal time slices. A custom one can have the time slices in the middle be longer.
For example:
public class CustomInterpolator implements Interpolator {
public boolean slowMode;
float lastInput;
float lastInputBeforeSlowed;
#Override
public float getInterpolation(float input) {
if (!slowMode) {
//Should be edited
lastInput = input;
return input;
} else {
return (input - lastInputBeforeSlowed) * .5f + lastInputBeforeSlowed;
}
}
public void enterSlowMode() {
slowMode = true;
lastInputBeforeSlowed = lastInput;
}
public void endSlowMode() {
slowMode = false;
//Should be edited
}
}

I have a NullPointerException using the SurfaceView

I have this code. It isn't complex at all, I'm learning and I was practising and messing around with the surface view. I only want 2 rectangles to be there and an image going down. When we touch in the second rectangle, the image starts going up. We touch the one in the left and the image restarts going down. When it arrives the line 89, it stops and gives the null pointer exception. I guess the error happens when I create the canvas.
public class LearningThreads extends Activity {
ActivitySurface activitySurface;
boolean crossGoesUp = false;//Sets if the cross goes up or down
int leftRectangle1, topRectangle1, rightRectangle1, bottomRectangle1;
int leftRectangle2, topRectangle2, rightRectangle2, bottomRectangle2;
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
activitySurface = new ActivitySurface(this);
activitySurface.setOnTouchListener(new canvasClicked());
setContentView(activitySurface);//Sets the content to be the class we've created
}
protected void onPause() {//When the app is paused, it calls the method which pauses the thread that is constantly running
super.onPause();
activitySurface.pause();
}
protected void onResume() {//When the app starts or restarts, it calls the method which starts the thread
super.onResume();
activitySurface.resume();
}
public class canvasClicked implements OnTouchListener {
public boolean onTouch(View v, MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {//Only if the user starts touching something because I'm not interested in when he releases
if (e.getX() <= leftRectangle1 && e.getX() >= rightRectangle1 && e.getY() <= topRectangle1 && e.getY() >= bottomRectangle1) {//Tests if the user touched one of the rectangles
crossGoesUp = false;
}
if (e.getX() <= leftRectangle2 && e.getX() >= rightRectangle2 && e.getY() <= topRectangle2 && e.getY() >= bottomRectangle2) {//Tests if the user touched the other rectangle
crossGoesUp = true;
}
}
return false;//It doesn't repeat
}
}
public class ActivitySurface extends SurfaceView {
Thread mainThread;
boolean isRunning = false;//Sets when the app is running or not
SurfaceHolder holder;//Gives us useful methods to use in the canvas
int crossY = 0;//Sets the y coordinate of the cross
public ActivitySurface(Context context) {
super(context);
holder = getHolder();
}
public void resume() {
isRunning = true;
mainThread = new Thread(new mainThread());
mainThread.start();
}
public void pause() {
isRunning = false;
try {
mainThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public class mainThread implements Runnable {//Takes care of the thread
public void run() {
while(isRunning) {
if (holder.getSurface().isValid())//Tests if the surface is valid, if it is not it won't do anything until it is
continue;
Canvas canvas = holder.lockCanvas();//Creating the canvas: it has a mistake, everytime I use the canvas it gives a NullPointerException
canvas.drawRGB(50, 50, 50);//Setting the color of the canvas
leftRectangle1 = canvas.getWidth()/4 - 40;//Setting the variables so they can be used outside this Thread
topRectangle1 = canvas.getHeight()/2 - 25;
rightRectangle1 = canvas.getWidth()/4 + 40;
bottomRectangle1 = canvas.getHeight()/2 + 25;
leftRectangle2 = canvas.getWidth()/4 + (canvas.getWidth()/4) * 2 - 40;
topRectangle2 = canvas.getHeight()/2 - 25;
rightRectangle2 = canvas.getWidth()/4 + (canvas.getWidth()/4) * 2 + 40;
bottomRectangle2 = canvas.getHeight()/2 + 25;
Paint paint = new Paint();//Setting the paint which will define the colors of the rectangles
paint.setARGB(0, 100, 100, 100);
Rect rectangle1 = new Rect();//Setting the position of the rectangle 1
rectangle1.set(leftRectangle1, topRectangle1, rightRectangle1, bottomRectangle1);
Rect rectangle2 = new Rect();//Setting the position of the rectangle 2
rectangle2.set(leftRectangle2, topRectangle2, rightRectangle2, bottomRectangle2);
canvas.drawRect(rectangle1, paint);//Drawing the rectangles
canvas.drawRect(rectangle2, paint);
Bitmap cross = BitmapFactory.decodeResource(getResources(), R.drawable.animation);//Creating the image which is going to go up and down
canvas.drawBitmap(cross, canvas.getWidth()/2 - cross.getWidth()/2, crossY, paint);
if (crossGoesUp) {//If the crossGoesUp is true, that means the user last touch was in the rectangle 2, so the image goes up
if (crossY < -cross.getHeight())//Tests if the image isn't out of bounds
crossY = canvas.getHeight() + cross.getHeight();
crossY -= 5;
} else {
if (crossY > canvas.getHeight() + cross.getHeight())//Same as above
crossY = -cross.getHeight();
crossY += 5;
}
holder.unlockCanvasAndPost(canvas);
}
}
}
}
}
This is my logcat:
05-02 07:13:41.897: E/AndroidRuntime(1634): FATAL EXCEPTION: Thread-103
05-02 07:13:41.897: E/AndroidRuntime(1634): Process: garden.apps.my_apps, PID: 1634
05-02 07:13:41.897: E/AndroidRuntime(1634): java.lang.NullPointerException
05-02 07:13:41.897: E/AndroidRuntime(1634): at com.apps.my_apps.LearningThreads$ActivitySurface$mainThread.run(LearningThreads.java:90)
05-02 07:13:41.897: E/AndroidRuntime(1634): at java.lang.Thread.run(Thread.java:841)
you should use SurfaceHolder.Callback, your paint is invisible
paint.setARGB(alpha,Red,Green,Blue) - alpha 0..255 0-invisible 255-visible
public class LearningThreads extends Activity {
ActivitySurface activitySurface;
boolean crossGoesUp = false;//Sets if the cross goes up or down
int leftRectangle1, topRectangle1, rightRectangle1, bottomRectangle1;
int leftRectangle2, topRectangle2, rightRectangle2, bottomRectangle2;
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
activitySurface = new ActivitySurface(this);
activitySurface.setOnTouchListener(new canvasClicked());
setContentView(activitySurface);//Sets the content to be the class we've created
}
protected void onPause() {//When the app is paused, it calls the method which pauses the thread that is constantly running
super.onPause();
}
protected void onResume() {//When the app starts or restarts, it calls the method which starts the thread
super.onResume();
}
public class canvasClicked implements View.OnTouchListener {
public boolean onTouch(View v, MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN) {//Only if the user starts touching something because I'm not interested in when he releases
if (e.getX() <= leftRectangle1 && e.getX() >= rightRectangle1 && e.getY() <= topRectangle1 && e.getY() >= bottomRectangle1) {//Tests if the user touched one of the rectangles
crossGoesUp = false;
}
if (e.getX() <= leftRectangle2 && e.getX() >= rightRectangle2 && e.getY() <= topRectangle2 && e.getY() >= bottomRectangle2) {//Tests if the user touched the other rectangle
crossGoesUp = true;
}
}
return false;//It doesn't repeat
}
}
public class ActivitySurface extends SurfaceView implements SurfaceHolder.Callback {
Thread mainThread;
boolean isRunning = false;//Sets when the app is running or not
SurfaceHolder holder;//Gives us useful methods to use in the canvas
int crossY = 0;//Sets the y coordinate of the cross
public ActivitySurface(Context context) {
super(context);
holder = getHolder();
holder.addCallback(this);
}
public void resume() {
isRunning = true;
mainThread = new Thread(new mainThread());
mainThread.start();
}
public void pause() {
isRunning = false;
try {
mainThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public class mainThread implements Runnable {//Takes care of the thread
public void run() {
while (isRunning) {
if (!holder.getSurface().isValid())//Tests if the surface is valid, if it is not it won't do anything until it is
continue;
Canvas canvas = holder.lockCanvas();//Creating the canvas: it has a mistake, everytime I use the canvas it gives a NullPointerException
canvas.drawRGB(50, 50, 50);//Setting the color of the canvas
leftRectangle1 = canvas.getWidth() / 4 - 40;//Setting the variables so they can be used outside this Thread
topRectangle1 = canvas.getHeight() / 2 - 25;
rightRectangle1 = canvas.getWidth() / 4 + 40;
bottomRectangle1 = canvas.getHeight() / 2 + 25;
leftRectangle2 = canvas.getWidth() / 4 + (canvas.getWidth() / 4) * 2 - 40;
topRectangle2 = canvas.getHeight() / 2 - 25;
rightRectangle2 = canvas.getWidth() / 4 + (canvas.getWidth() / 4) * 2 + 40;
bottomRectangle2 = canvas.getHeight() / 2 + 25;
Paint paint = new Paint();//Setting the paint which will define the colors of the rectangles
paint.setARGB(255, 100, 100, 100);
Rect rectangle1 = new Rect();//Setting the position of the rectangle 1
rectangle1.set(leftRectangle1, topRectangle1, rightRectangle1, bottomRectangle1);
Rect rectangle2 = new Rect();//Setting the position of the rectangle 2
rectangle2.set(leftRectangle2, topRectangle2, rightRectangle2, bottomRectangle2);
canvas.drawRect(rectangle1, paint);//Drawing the rectangles
canvas.drawRect(rectangle2, paint);
Bitmap cross = BitmapFactory.decodeResource(getResources(), R.drawable.animation);//Creating the image which is going to go up and down
canvas.drawBitmap(cross, canvas.getWidth() / 2 - cross.getWidth() / 2, crossY, paint);
if (crossGoesUp) {//If the crossGoesUp is true, that means the user last touch was in the rectangle 2, so the image goes up
if (crossY < -cross.getHeight())//Tests if the image isn't out of bounds
crossY = canvas.getHeight() + cross.getHeight();
crossY -= 5;
} else {
if (crossY > canvas.getHeight() + cross.getHeight())//Same as above
crossY = -cross.getHeight();
crossY += 5;
}
holder.unlockCanvasAndPost(canvas);
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
resume();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
pause();
}
}
someActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
//Your code to run in GUI thread here
}//public void run() {
});
I hope this will help you.
I managed to figger it out by myself, the problem was in this block of code:
if (holder.getSurface().isValid())//Tests if the surface is valid, if it is not it won't do anything until it
continue;
I forgot to put the exclamation mark, so the app only did what was below when the surface was not valid and it gave me a NullPointerException.
Thank you anyway.

AsyncTask onDraw method with time delay

I want to make an activity where user at the beginning will see first statement then after 2 sec, there'll be second statement and at last there show up timer with progress drawn on canvas in onDraw method.
Timer should only last 5 seconds, but when I add those two 2 sec breaks, user will see only last second (5-2-2). I tried to change code where progress is calculated, but I just make things worse.
I cutted out variable declaration and all content about shapes being drawing. Maybe i should declarate in diffrent moment startTime and currentTime.
public class CircleTimer extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final CircularCountdown view = new CircularCountdown(this);
setContentView(view);
AsyncTask<Void, Boolean, Void> task = new AsyncTask<Void, Boolean, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(2000);
publishProgress(true);
Thread.sleep(2000);
} catch (InterruptedException e) {
}
return null;
}
protected void onProgressUpdate(Boolean... progress) {
view.setSecondDrawStep(progress[0]);
view.invalidate();
}
#Override
protected void onPostExecute(Void result) {
view.setThirdDrawStep(true);
view.invalidate();
}
};
task.execute((Void[])null);
}
private class CircularCountdown extends View {
public CircularCountdown(Context context) {
super(context);
maxTime = 5000;
startTime = System.currentTimeMillis();
currentTime = startTime;
viewHandler = new Handler();
updateView = new Runnable(){
#Override
public void run(){
currentTime = System.currentTimeMillis();
progressMillisecond = Math.abs(startTime - currentTime) % maxTime;
progress = (double) (progressMillisecond) / maxTime;
CircularCountdown.this.invalidate();
viewHandler.postDelayed(updateView, 1000/60);
}
};
viewHandler.post(updateView);
}
boolean secondDrawStep = false;
boolean thirdDrawStep = false;
public void setSecondDrawStep(boolean flag) {
secondDrawStep = flag;
}
public void setThirdDrawStep(boolean flag) {
thirdDrawStep = flag;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText("FIRST statement",
centerWidthCenter,
centerHeightCenter + textOffset,
nameTextPaint);
if (secondDrawStep) {
canvas.drawColor(Color.WHITE);
canvas.drawText("SECOND statement",
centerWidthCenter,
centerHeightCenter + textOffset,
nameTextPaint);
}
if (thirdDrawStep) {
canvas.drawColor(Color.WHITE);
canvas.drawArc(circleBounds, -90, (float) (progress * 360), false, progressPaint);
canvas.drawText((int) Math.abs(5 - (progressMillisecond / 1000)) + "s",
centerWidth,
centerHeight + textOffset,
textPaint);
}
}
}
}

Categories

Resources