2015-04-01 26 views
45

Voglio sviluppare un componente personalizzato che disegna parte del cerchio in base a valori diversi. per esempio disegnare 1/4 di cerchio, 1/2 cerchio ecc. Il componente deve essere animato per visualizzare il processo di disegno. Il cerchio parziale viene disegnato sopra una vista di immagini statica e ho intenzione di utilizzare due viste, una animata sopra quella statica. Qualche suggerimento su come svilupparlo?Come disegnare un cerchio con animazione in Android con dimensione del cerchio basata su un valore

Ho messo lo screenshot come riferimento.

enter image description here

prega di fare riferimento al quadro, e avere un'idea di come sembra. Grazie!

Grazie in anticipo.

risposta

119

Devi disegnare la vista del cerchio e dopo devi creare un'animazione.

Creare la vista cerchio:

public class Circle extends View { 

    private static final int START_ANGLE_POINT = 90; 

    private final Paint paint; 
    private final RectF rect; 

    private float angle; 

    public Circle(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     final int strokeWidth = 40; 

     paint = new Paint(); 
     paint.setAntiAlias(true); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeWidth(strokeWidth); 
     //Circle color 
     paint.setColor(Color.RED); 

     //size 200x200 example 
     rect = new RectF(strokeWidth, strokeWidth, 200 + strokeWidth, 200 + strokeWidth); 

     //Initial Angle (optional, it can be zero) 
     angle = 120; 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawArc(rect, START_ANGLE_POINT, angle, false, paint); 
    } 

    public float getAngle() { 
     return angle; 
    } 

    public void setAngle(float angle) { 
     this.angle = angle; 
    } 
} 

Creazione della classe di animazione per impostare il nuovo angolo: cerchio

public class CircleAngleAnimation extends Animation { 

    private Circle circle; 

    private float oldAngle; 
    private float newAngle; 

    public CircleAngleAnimation(Circle circle, int newAngle) { 
     this.oldAngle = circle.getAngle(); 
     this.newAngle = newAngle; 
     this.circle = circle; 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation transformation) { 
     float angle = oldAngle + ((newAngle - oldAngle) * interpolatedTime); 

     circle.setAngle(angle); 
     circle.requestLayout(); 
    } 
} 

mettete nel vostro layout:

<com.package.Circle 
    android:id="@+id/circle" 
    android:layout_width="300dp" 
    android:layout_height="300dp" /> 

E infine l'avvio del animazione:

Circle circle = (Circle) findViewById(R.id.circle); 

CircleAngleAnimation animation = new CircleAngleAnimation(circle, 240); 
animation.setDuration(1000); 
circle.startAnimation(animation); 

Il risultato è: enter image description here

+0

Grazie John, apprezzare Marcus. Controllerò il codice e darò il mio feedback. Il codice –

+0

funziona correttamente. Grazie. –

+3

Se il codice funziona, si prega di impostare come risposta alla domanda. –

0

come extra dalla risposta @JohnCordeiro. Ho aggiunto parametri da xml per riutilizzare il cerchio e riempire il cerchio se necessario.

class RecordingCircle(context: Context, attrs: AttributeSet) : View(context, attrs) { 

private val paint: Paint 
private val rect: RectF 

private val fillPaint: Paint 
private val fillRect: RectF 

var angle: Float 
var startAngle: Float 

init { 
    val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecordingCircle) 
    startAngle = typedArray.getFloat(R.styleable.RecordingCircle_startAngle, 0f) 
    val offsetAngle = typedArray.getFloat(R.styleable.RecordingCircle_offsetAngle, 0f) 
    val color = typedArray.getColor(R.styleable.RecordingCircle_color, ResourcesCompat.getColor(resources, R.color.recording, null)) 
    val strokeWidth = typedArray.getFloat(R.styleable.RecordingCircle_strokeWidth, 20f) 
    val circleSize = typedArray.getDimension(R.styleable.RecordingCircle_cicleSize, 100f) 
    val fillColor = typedArray.getColor(R.styleable.RecordingCircle_fillColor, 0) 
    typedArray.recycle() 

    paint = Paint().apply { 
     setAntiAlias(true) 
     setStyle(Paint.Style.STROKE) 
     setStrokeWidth(strokeWidth) 
     setColor(color) 
    } 

    rect = RectF(
     strokeWidth, 
     strokeWidth, 
     (circleSize - strokeWidth), 
     (circleSize - strokeWidth) 
    ) 

    fillPaint = Paint().apply { 
     setAntiAlias(true) 
     setStyle(Paint.Style.FILL) 
     setColor(fillColor) 
    } 

    val offsetFill = strokeWidth 
    fillRect = RectF(
     offsetFill, 
     offsetFill, 
     (circleSize - offsetFill), 
     (circleSize - offsetFill) 
    ) 

    //Initial Angle (optional, it can be zero) 
    angle = offsetAngle 
} 

override protected fun onDraw(canvas: Canvas) { 
    super.onDraw(canvas) 
    if (fillColor > 0) { 
     canvas.drawArc(rect, 0f, 360f, false, fillPaint) 
    } 
    canvas.drawArc(rect, startAngle, angle, false, paint) 
} 
} 

E sul xml:

 <com.myapp.RecordingCircle android:id="@+id/cameraRecordButton" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:offsetAngle="360" 
     app:color="@color/light_grey" 
     app:strokeWidth="10" 
     app:cicleSize="@dimen/camera_record_button" 
     app:fillColor="@color/recording_bg" /> 

    <com.myapp.RecordingCircle android:id="@+id/progress" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:startAngle="270" 
     app:color="@color/recording" 
     app:strokeWidth="10" 
     app:cicleSize="@dimen/camera_record_button" /> 

Ecco il risultato: Nota il riempimento semitrasparente del pulsante

enter image description here

Problemi correlati