Showing posts with label Android code sample: CountDownTimer. Show all posts
Showing posts with label Android code sample: CountDownTimer. Show all posts

Tuesday, June 10, 2014

Use CountDownTimer to do something repeatly, second example.

It is another approach to do the same job as the previous example "Use CountDownTimer to do something repeatly, updating custom view". Instead of implementing CountDownTimer inside custom view as self running function of custom view, this example implement CountDownTimer in MainActivity, and handle all the timing functions. The custom view simple display the graphic only.


MainActivity.java
package com.example.androidcountdowntimer;

import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity{
 
 CountDownTimer countDownTimer;
  
 int state;
 final static int STATE_IDLE = 0;
 final static int STATE_RED = 1;
 final static int STATE_GREEN = 2;
 final static int STATE_BLUE = 3;

 TextView myState, myCounter;
 Button btnStart;
 
 SpotView mySpotView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  mySpotView = (SpotView)findViewById(R.id.myspotview);

  myState = (TextView) findViewById(R.id.mystate);
  
  myCounter = (TextView) findViewById(R.id.mycounter);
  btnStart = (Button) findViewById(R.id.start);
  btnStart.setOnClickListener(btnStartOnClickListener);
  
  state = STATE_IDLE;

 }
 
 OnClickListener btnStartOnClickListener = 
  new OnClickListener(){

   @Override
   public void onClick(View v) {
    
    if(countDownTimer!=null){
       countDownTimer.cancel();   
    }
    
    state = STATE_RED;
    
    countDownTimer = new CountDownTimer(3000, 500) {

     @Override
     public void onTick(long millisUntilFinished) {
      myCounter.setText("onTick: " + millisUntilFinished);
     }

     @Override
     public void onFinish() {
      if(state == STATE_RED){
       state = STATE_GREEN;
       mySpotView.setSpots(false, true, false);
       myState.setText("GREEN");
      }else if(state == STATE_GREEN){
       state = STATE_BLUE;
       mySpotView.setSpots(false, false, true);
       myState.setText("BLUE");
      }else if(state == STATE_BLUE){
       state = STATE_RED;
       mySpotView.setSpots(true, false, false);
       myState.setText("RED");
      }
      
      countDownTimer.start(); 
     }
    };
    
    mySpotView.setSpots(true, false, false);
    myState.setText("RED");
    countDownTimer.start();
   }  
 };

}

SpotView.java
package com.example.androidcountdowntimer;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class SpotView extends View{
 
 boolean spotRedOn, spotGreenOn, spotBlueOn;
 
 Paint paintRed, paintGreen, paintBlue;

 public SpotView(Context context) {
  super(context);
  init();
 }

 public SpotView(Context context, AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public SpotView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }
 
 private void init(){

  paintRed = new Paint();
  paintRed.setColor(Color.RED);
  paintRed.setStrokeWidth(1);
  paintRed.setStyle(Paint.Style.FILL);
  
  paintGreen = new Paint();
  paintGreen.setColor(Color.GREEN);
  paintGreen.setStrokeWidth(1);
  paintGreen.setStyle(Paint.Style.FILL);
  
  paintBlue = new Paint();
  paintBlue.setColor(Color.BLUE);
  paintBlue.setStrokeWidth(1);
  paintBlue.setStyle(Paint.Style.FILL);
  
  spotRedOn = spotGreenOn = spotBlueOn = false;
 }

 
 public void setSpots(boolean r, boolean g, boolean b){
  spotRedOn = r;
  spotGreenOn = g;
  spotBlueOn = b;
  invalidate();
 }

 @Override
 protected void onDraw(Canvas canvas) {
  
  float w = getWidth();
  float h = getHeight();
  
  if(spotRedOn){
   canvas.drawCircle(w/4, h/2, 100, paintRed);
  }
  
  if(spotGreenOn){
   canvas.drawCircle(w/2, h/2, 100, paintGreen);
  }
  
  if(spotBlueOn){
   canvas.drawCircle(3*w/4, h/2, 100, paintBlue);
  }
 }

}

Keep using the same layout in previous example.

Monday, June 9, 2014

Use CountDownTimer to do something repeatly, updating custom view.

This example show how to change color spots in custom view repeatly with CountDownTimer. We also implement callback interface on MainActivity.java, such that our custom view can callback MainActivity to pass something.

May be it is not a good practice to achieve such a job, just a example to use CountDownTimer.


MainActivity.java
package com.example.androidcountdowntimer;

import com.example.androidcountdowntimer.SpotView.SpotCallBack;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity 
  implements SpotCallBack{

 TextView myState, myCounter;
 Button btnStart;
 
 SpotView mySpotView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  mySpotView = (SpotView)findViewById(R.id.myspotview);
  mySpotView.setCallback(this);

  myState = (TextView) findViewById(R.id.mystate);
  
  myCounter = (TextView) findViewById(R.id.mycounter);
  btnStart = (Button) findViewById(R.id.start);
  btnStart.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View v) {
    mySpotView.startRun();
   }
  });

 }

 @Override
 public void cb_onTick(String msg) {
  myCounter.setText("onTick: " + msg);
 }

 @Override
 public void cb_onFinish(String msg) {
  myState.setText(msg);
 }

}

SpotView.java
package com.example.androidcountdowntimer;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.view.View;

public class SpotView extends View{
 
 //used to pass back something to MainActivity
 interface SpotCallBack {
  void cb_onTick(String msg);
  void cb_onFinish(String msg); 
 }
 
 SpotCallBack spotCallback;
 
 CountDownTimer countDownTimer;
 
 int state;
 final static int STATE_IDLE = 0;
 final static int STATE_RED = 1;
 final static int STATE_GREEN = 2;
 final static int STATE_BLUE = 3;
 
 Paint paintRed, paintGreen, paintBlue;

 public SpotView(Context context) {
  super(context);
  init();
 }

 public SpotView(Context context, AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public SpotView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }
 
 private void init(){
  state = STATE_IDLE;
  
  paintRed = new Paint();
  paintRed.setColor(Color.RED);
  paintRed.setStrokeWidth(1);
  paintRed.setStyle(Paint.Style.FILL);
  
  paintGreen = new Paint();
  paintGreen.setColor(Color.GREEN);
  paintGreen.setStrokeWidth(1);
  paintGreen.setStyle(Paint.Style.FILL);
  
  paintBlue = new Paint();
  paintBlue.setColor(Color.BLUE);
  paintBlue.setStrokeWidth(1);
  paintBlue.setStyle(Paint.Style.FILL);
 }
 
 public void setCallback(SpotCallBack cb){
  spotCallback = cb;
 }
 
 public void startRun(){
  state = STATE_RED;
  
  if(countDownTimer!=null){
   countDownTimer.cancel();
  }
  
  countDownTimer = new CountDownTimer(3000, 500) {
   
   @Override
   public void onTick(long millisUntilFinished) {
    spotCallback.cb_onTick(String.valueOf(millisUntilFinished));
   }
   
   @Override
   public void onFinish() {
    if(state == STATE_RED){
     state = STATE_GREEN;
     spotCallback.cb_onFinish("GREEN");
    }else if(state == STATE_GREEN){
     state = STATE_BLUE;
     spotCallback.cb_onFinish("BLUE");
    }else if(state == STATE_BLUE){
     state = STATE_RED;
     spotCallback.cb_onFinish("RED");
    }
    countDownTimer.start();
    invalidate();
   }
  };
  
  countDownTimer.start();
  spotCallback.cb_onFinish("RED");
  invalidate();
 }

 @Override
 protected void onDraw(Canvas canvas) {
  
  float w = getWidth();
  float h = getHeight();
  
  if(state == STATE_RED){
   canvas.drawCircle(w/4, h/2, 100, paintRed);
  }else if(state == STATE_GREEN){
   canvas.drawCircle(w/2, h/2, 100, paintGreen);
  }else if(state == STATE_BLUE){
   canvas.drawCircle(3*w/4, h/2, 100, paintBlue);
  }
 }

}

/res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.androidcountdowntimer.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Start CountDownTimer" />
    <TextView
        android:id="@+id/mystate"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/mycounter"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <com.example.androidcountdowntimer.SpotView 
        android:id="@+id/myspotview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

Next example:
- Another approach to handle CountDownTimer in MainActivity, and the custom view handle display only.

Saturday, June 7, 2014

Restart CountDownTimer

Refer to my old exercise of "Count Down Timer", it is a one-shot CountDownTimer. In some case you want to reset/restart the CountDownTimer, you have to cancel the old one if exist, otherwise both old and new CountDownTimer will run together.

Example:


MainActivity.java
package com.example.androidcountdowntimer;

import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

 TextView myCounter;
 Button btnStart;
 CountDownTimer countDownTimer;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  myCounter = (TextView) findViewById(R.id.mycounter);
  btnStart = (Button) findViewById(R.id.start);
  btnStart.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View v) {

    //cancel the old countDownTimer 
    if(countDownTimer!=null){
     countDownTimer.cancel();
    }
    
    countDownTimer = new CountDownTimer(10000, 1000) {

     @Override
     public void onFinish() {
      myCounter.setText("Finished!");
     }

     @Override
     public void onTick(long millisUntilFinished) {
      myCounter.setText("Millisecond Until Finished: "
        + String.valueOf(millisUntilFinished));
     }

    };
    
    countDownTimer.start();
   }
  });

 }

}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.androidcountdowntimer.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />

    <Button
        android:id="@+id/start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Start CountDownTimer" />
    <TextView
        android:id="@+id/mycounter"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

Next:
- Use CountDownTimer to do something repeatly, updating custom view; handle CountDownTimer in custom view.
- Another approach to use CountDownTimer to do something repeatly; handle CountDownTimer in MainActivity, custom view handle display only.