2015-04-01 5 views
45

Ich möchte eine benutzerdefinierte Komponente entwickeln, die einen Teil des Kreises basierend auf verschiedenen Werten zeichnet. z. B. 1/4 Kreis, 1/2 Kreis usw. zeichnen. Die Komponente muss animiert werden, um den Zeichenprozess anzuzeigen. Der Teilkreis wird über einer statischen Bildansicht gezeichnet, und ich plane, zwei Ansichten zu verwenden, eine animierte über der statischen. Irgendwelche Vorschläge, wie man das entwickelt?Wie zeichne ich einen Kreis mit Animation in android mit Kreisgröße basierend auf einem Wert

Ich legte den Screenshot als Referenz.

enter image description here

entnehmen Sie bitte das Bild, und ein Gefühl dafür bekommen, wie es aussieht. Danke!

Vielen Dank im Voraus.

Antwort

119

Sie müssen die Kreisansicht zeichnen, und danach sollten Sie eine Animation erstellen.

den Kreis Ansicht erstellen:

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; 
    } 
} 

die Animation Klasse Erstellen des neuen Blickwinkel zu setzen:

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(); 
    } 
} 

Put Kreis in Ihr Layout:

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

Und endlich beginnen, die Animation:

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

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

Das Ergebnis ist: enter image description here

+0

Dank John, Marcus schätzen. Ich werde den Code überprüfen und mein Feedback geben. –

+0

Code funktioniert gut. Vielen Dank. –

+3

Wenn Code funktioniert, legen Sie bitte als Antwort auf die Frage fest. –

0

Als zusätzliche aus @JohnCordeiro Antwort. Ich habe Parameter aus XML hinzugefügt, um den Kreis wiederzuverwenden und den Kreis bei Bedarf zu füllen.

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) 
} 
} 

Und auf der 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" /> 

Hier das Ergebnis: Notiere die halbtransparente Füllung der Taste

enter image description here

Verwandte Themen