2012-06-19 1 views
0

Je crée le compte à rebours de Noël et j'ai besoin de compter à chaque seconde et besoin de dessiner sur la toile combien de jours, heures, minutes et secondes à Noël.Android CountDownTimer et dessiner sur la toile

Je pourrais obtenir la sortie de travail, mais je pense qu'il y a un bon moyen d'y parvenir que ce que je fais maintenant.

Voici le code, et j'ai enlevé quelques codes inutiles comme les importations, les méthodes inappliquées etc.

public class SnowFall extends Activity { 

SampleView textDraw; 
Paint paint; 
Rect bounds; 
int durationMilli; 
Duration duration; 

static String days; 
static String hours; 
static String minutes; 
static String seconds; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Duration duration = new Duration(); 
    int futureTime = duration.cal_duration(); 
    MyTime tm = new MyTime(futureTime, 1000); 
    tm.start(); 

    textDraw = new SampleView(this); 

    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    LinearLayout linearLayout = new LinearLayout(this); 
    linearLayout.setOrientation(LinearLayout.VERTICAL); 
    linearLayout.setBackgroundColor(Color.TRANSPARENT); 
    textDraw.setBackgroundDrawable(getResources().getDrawable(
      R.drawable.background_image_1)); 
    linearLayout.addView(textDraw); 
    setContentView(linearLayout); 

} 

public class MyTime extends CountDownTimer { 

    public MyTime(long millisInFuture, long countDownInterval) { 
     super(millisInFuture, countDownInterval); 

    } 

    @Override 
    public void onTick(long millisUntilFinished) { 

     SampleView view = new SampleView(getApplicationContext()); 
     int durationInMilliSec = (int) millisUntilFinished; 
     Log.d("Joda Time", String.valueOf(durationInMilliSec)); 

     try { 
      int x = durationInMilliSec/1000; 
      seconds = String.valueOf(x % 60); 
      x /= 60; 
      minutes = String.valueOf(x % 60); 
      x /= 60; 
      hours = String.valueOf(x % 24); 
      x /= 24; 
      days = String.valueOf(x); 

      view.invalidate(); 
     } catch (Exception e) { 

     } 

    } 

} 

private static class SampleView extends View { 
    private Paint mPaint; 
    private float mX; 
    private float[] mPos; 

    private Path mPath; 
    private Paint mPathPaint; 

    private static final int DY = 45; 
    private static final String POSTEXT = "Positioned"; 

    private static void makePath(Path p) { 
     p.moveTo(10, 0); 
     p.cubicTo(100, -50, 200, 50, 300, 0); 
    } 

    private float[] buildTextPositions(String text, float y, Paint paint) { 
     float[] widths = new float[text.length()]; 
     // initially get the widths for each char 
     int n = paint.getTextWidths(text, widths); 
     // now popuplate the array, interleaving spaces for the Y values 
     float[] pos = new float[n * 2]; 
     float accumulatedX = 0; 
     for (int i = 0; i < n; i++) { 
      pos[i * 2 + 0] = accumulatedX; 
      pos[i * 2 + 1] = y; 
      accumulatedX += widths[i]; 
     } 
     return pos; 
    } 

    public SampleView(Context context) { 
     super(context); 
     setFocusable(true); 

     mPaint = new Paint(); 
     mPaint.setAntiAlias(true); 
     mPaint.setTextSize(40); 
     Typeface typeface = Typeface.createFromAsset(context.getAssets(), 
       "font.ttf"); 
     mPaint.setTypeface(typeface); 

     mPos = buildTextPositions(POSTEXT, 0, mPaint); 

     mPath = new Path(); 
     makePath(mPath); 

     mPathPaint = new Paint(); 
     mPathPaint.setAntiAlias(true); 
     mPathPaint.setColor(0x800000FF); 
     mPathPaint.setStyle(Paint.Style.STROKE); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     Paint p = mPaint; 
     float x = mX; 
     float y = 0; 

     if (days != null && hours != null && minutes != null 
       && seconds != null) { 
      canvas.translate(0, DY); 
      p.setTextAlign(Paint.Align.CENTER); 
      canvas.drawText("There is", x, y, p); 

      canvas.translate(0, DY); 
      p.setTextAlign(Paint.Align.CENTER); 
      canvas.drawText(days + " Days, " + hours + " Hours", x, y, p); 

      canvas.translate(0, DY); 
      p.setTextAlign(Paint.Align.CENTER); 
      canvas.drawText(minutes + " Minutes and " + seconds 
        + " seconds", x, y, p); 

      canvas.translate(0, DY); 
      p.setTextAlign(Paint.Align.CENTER); 
      canvas.drawText("until christmas.", x, y, p); 

      invalidate(); 

     } else { 

      // draw the normal strings 
      canvas.translate(0, DY); 
      p.setTextAlign(Paint.Align.CENTER); 
      canvas.drawText("Something Wrong", x, y, p); 

      canvas.translate(0, DY); 
      p.setTextAlign(Paint.Align.CENTER); 
      canvas.drawText("Check your device time.", x, y, p); 

     } 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int ow, int oh) { 
     super.onSizeChanged(w, h, ow, oh); 
     mX = w * 0.5f; // remember the center of the screen 
    } 

} 

} 

Et il est petit problème avec compter combien de jours, car il montre qu'il ya seulement 10 jours Noël. Je ne savais rien sur les graphiques sur Android, a travaillé dur sur ce sujet.

package in.isuru.animation; 

import org.joda.time.DateTime; 
import org.joda.time.Seconds; 

public class Duration { 

public int cal_duration(){ 
    DateTime start = new DateTime(DateTime.now()); 
    DateTime end = new DateTime(2012, 12, 25, 0, 0, 0 ,0); 
    int differenceSeconds = Seconds.secondsBetween(end, start).getSeconds(); 

    return differenceSeconds * 1000; 
} 

} 

Le problème est sur chaque Tick il calcule jours, heures, minutes et secondes. S'il vous plaît donnez-moi des commentaires sur si c'est bon ou y at-il un meilleur moyen?

Répondre

0

Vos numéros seront erronés car vous déborderez le type de données int en millisecondes. La valeur maximale d'un int est 2^31 ~ 2 x 10^9. Il reste environ 155 x 10^9 millisecondes jusqu'à Noël.

Il suffit de calculer les secondes et tout ira bien. Ou vous pouvez utiliser un long 64 bits au lieu de int. Mais vous multipliez par 1000 pour obtenir des millisecondes et ensuite divisez par 1000 immédiatement! Cela n'a pas beaucoup de sens.

Mieux encore suivre avec Joda temps!

Puisque vous l'utilisez déjà, pourquoi ne pas construire une période?

DateTime start = DateTime.now(); // Note your code makes an unneeded copy here 
DateTime end = new DateTime(2012, 12, 25, 0, 0, 0); 
Period p = new Period(start, end); 

Cette période comporte des getters depuis des années, mois, jours, heures, minutes, secondes. Cela évitera complètement le calcul sujet à erreur.

3

il suffit d'utiliser ce code simple

countDownTimer = new CountDownTimer(240000, 1000) { 

    public void onTick(long millisUntilFinished) { 
     int seconds = (int) ((millisUntilFinished/1000)%60); 
     int minutes = (int) ((millisUntilFinished/1000)/60); 
     int hours = (int) ((millisUntilFinished/1000)/3600); 
     String startTime ="Time " + String.format("%02d:%02d:%02d",hours,minutes,seconds); 
     txtShowTimer.setText(startTime); 
    } 

    public void onFinish() { 
     txtShowTimer.setText("done!"); 
    } 
}.start(); 
+1

Mieux expliquer un peu plus de laisser OP avoir une meilleure idée pourquoi il ne le fait pas droit. – WiSaGaN

Questions connexes