2013-01-25 12 views
11

Sto sviluppando un'applicazione & appena costruita la sua parte logica. Ora voglio progettare questo app come nei famosi esempi timer apps.for:Come posso programmare un'animazione circolare circolare come questa (immagine allegata)? Android

http://goo.gl/N3qS1
enter image description here

La cosa che voglio è il cerchio esterno che si riempie di ogni trigger di qualche evento o con incremento del numero. In realtà non so che è una parte dell'animazione (come essere costruita in flash o cosa) o semplicemente possibile tramite la codifica in Android stesso utilizzando le sue proprietà e caratteristiche incorporate. Quindi, se qualcuno mi dice quali strumenti sono usati o qualsiasi tutorial di riferimento che possa spiegare le cose dal basso. Non so davvero nulla di progettazione. Qualche codice per questo ??

+0

È precedenza tagged questa domanda Core Animation (iOS quadro). Potrei dirti come funziona su iOS ma dubito che risponda alla tua domanda. –

+0

Non sapevo che il suo framework iOS. Ho pensato che fosse solo l'animazione legata al core o qualcosa del genere. Colpa mia – Aexyn

+0

@ DavidRönnqvist potresti fornire un collegamento per l'implementazione iOS di questo? –

risposta

0

È possibile definire un'animazione all'interno di Android, ma sarà necessario "tagliare" l'animazione in pezzi e riassemblarla mentre in Android.

http://digitaldumptruck.jotabout.com/?p=813 questo dovrebbe essere l'articolo il vostro ricerca;)

+0

Link is rotto. –

6

Questo farà?

Aggiornamento: Ora gestisce correttamente anche il tempo reale.

Schermata di esempio:Sample screenshot

Codice:

import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.os.Handler; 
import android.text.TextPaint; 
import android.view.View; 

import android.graphics.*; 


public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(new CircularCountdown(this)); 
    } 

    private static class CircularCountdown extends View { 

     private final Paint backgroundPaint; 
     private final Paint progressPaint; 
     private final Paint textPaint; 

     private long startTime; 
     private long currentTime; 
     private long maxTime; 

     private long progressMillisecond; 
     private double progress; 

     private RectF circleBounds; 
     private float radius; 
     private float handleRadius; 
     private float textHeight; 
     private float textOffset; 

     private final Handler viewHandler; 
     private final Runnable updateView; 

     public CircularCountdown(Context context) { 
      super(context); 

      // used to fit the circle into 
      circleBounds = new RectF(); 

      // size of circle and handle 
      radius = 200; 
      handleRadius = 10; 

      // limit the counter to go up to maxTime ms 
      maxTime = 5000; 

      // start and current time 
      startTime = System.currentTimeMillis(); 
      currentTime = startTime; 


      // the style of the background 
      backgroundPaint = new Paint(); 
      backgroundPaint.setStyle(Paint.Style.STROKE); 
      backgroundPaint.setAntiAlias(true); 
      backgroundPaint.setStrokeWidth(10); 
      backgroundPaint.setStrokeCap(Paint.Cap.SQUARE); 
      backgroundPaint.setColor(Color.parseColor("#4D4D4D")); // dark gray 

      // the style of the 'progress' 
      progressPaint = new Paint(); 
      progressPaint.setStyle(Paint.Style.STROKE); 
      progressPaint.setAntiAlias(true); 
      progressPaint.setStrokeWidth(10); 
      progressPaint.setStrokeCap(Paint.Cap.SQUARE); 
      progressPaint.setColor(Color.parseColor("#00A9FF")); // light blue 

      // the style for the text in the middle 
      textPaint = new TextPaint(); 
      textPaint.setTextSize(radius/2); 
      textPaint.setColor(Color.BLACK); 
      textPaint.setTextAlign(Paint.Align.CENTER); 

      // text attributes 
      textHeight = textPaint.descent() - textPaint.ascent(); 
      textOffset = (textHeight/2) - textPaint.descent(); 


      // This will ensure the animation will run periodically 
      viewHandler = new Handler(); 
      updateView = new Runnable(){ 
       @Override 
       public void run(){ 
        // update current time 
        currentTime = System.currentTimeMillis(); 

        // get elapsed time in milliseconds and clamp between <0, maxTime> 
        progressMillisecond = (currentTime - startTime) % maxTime; 

        // get current progress on a range <0, 1> 
        progress = (double) progressMillisecond/maxTime; 

        CircularCountdown.this.invalidate(); 
        viewHandler.postDelayed(updateView, 1000/60); 
       } 
      }; 
      viewHandler.post(updateView); 
     } 



     @Override 
     protected void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 

      // get the center of the view 
      float centerWidth = canvas.getWidth()/2; 
      float centerHeight = canvas.getHeight()/2; 


      // set bound of our circle in the middle of the view 
      circleBounds.set(centerWidth - radius, 
        centerHeight - radius, 
        centerWidth + radius, 
        centerHeight + radius); 


      // draw background circle 
      canvas.drawCircle(centerWidth, centerHeight, radius, backgroundPaint); 

      // we want to start at -90°, 0° is pointing to the right 
      canvas.drawArc(circleBounds, -90, (float)(progress*360), false, progressPaint); 

      // display text inside the circle 
      canvas.drawText((double)(progressMillisecond/100)/10 + "s", 
          centerWidth, 
          centerHeight + textOffset, 
          textPaint); 

      // draw handle or the circle 
      canvas.drawCircle((float)(centerWidth + (Math.sin(progress * 2 * Math.PI) * radius)), 
           (float)(centerHeight - (Math.cos(progress * 2 * Math.PI) * radius)), 
           handleRadius, 
           progressPaint); 
     } 

    } 

} 
+0

Ehi! Questo sembra davvero fantastico. È possibile utilizzare solo una parte dell'attività? Lo voglio nella parte inferiore della mia attività e uso altri elementi nella parte superiore. – mathletics

+1

@adamNature Naturalmente. Basta prendere la classe statica interna CircularCountdown e utilizzarla come qualsiasi altra vista. (Probabilmente dovresti anche trovare un modo migliore per gestire la dimensione del cerchio, perché ora è stato risolto 200 unità di qualcosa e puoi aspettarti che si romperà su schermi di diverse dimensioni.) – Antimonit

+0

Sì, grazie!Ho funzionato solo un paio d'ore dopo aver chiesto, naturalmente, stupido. È una grande classe, anche con il mio plebeo capire di Android sono in grado di fare cose divertenti con esso. Molte grazie! – mathletics