tutorial studio programacion móviles evento español ejemplo dibujar desarrollo curso aplicaciones android animation draw

programacion - evento touch android studio



Cómo dibujar un círculo con animación en Android con un tamaño de círculo basado en un valor (3)

Código agregado para calcular medidas de círculo correctas

import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.RectF import android.util.AttributeSet import android.view.View import androidx.core.content.ContextCompat class Circle(context: Context, attrs: AttributeSet) : View(context, attrs) { private val paint: Paint private val rect: RectF var angle = 0f companion object { private val START_ANGLE_POINT = 270f } init { val strokeWidth = resources.getDimension(R.dimen.toast_circle_stroke_width) paint = Paint().apply { setAntiAlias(true) setStyle(Paint.Style.STROKE) setStrokeWidth(strokeWidth) setColor(Color.RED) } val circleSize = resources.getDimension(R.dimen.toast_circle_size) rect = RectF( strokeWidth, strokeWidth, circleSize + strokeWidth, circleSize + strokeWidth ) } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { val circleSize = resources.getDimension(R.dimen.toast_circle_size).toInt() val strokeWidth = resources.getDimension(R.dimen.toast_circle_stroke_width).toInt() super.onMeasure( MeasureSpec.makeMeasureSpec(circleSize + 2 * strokeWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(circleSize + 2 * strokeWidth, MeasureSpec.EXACTLY)); } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawArc(rect, START_ANGLE_POINT, angle, false, paint) } }

Quiero desarrollar un componente personalizado que dibuje parte del círculo en función de diferentes valores. por ejemplo, dibujar 1/4 de círculo, 1/2 círculo, etc. El componente debe ser animado para mostrar el proceso de dibujo. El círculo parcial se dibuja en la parte superior de una vista de imagen estática, y planeo usar dos vistas, animadas, una encima de la vista estática. ¿Alguna sugerencia de cómo desarrollar esto?

Puse la captura de pantalla como referencia.

Consulte la imagen y tenga una idea de cómo se ve. ¡Gracias!

Gracias por adelantado.


Como extra de la respuesta de @JohnCordeiro. He agregado parámetros de xml para reutilizar el círculo y llenar el círculo si es necesario.

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

Y en el 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" />

Aquí el resultado: observe el relleno semitransparente del botón


Tienes que dibujar la vista circular, y luego debes crearle una animación.

Crear la vista circular:

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

Crear la clase de animación para establecer el nuevo ángulo:

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

Poner círculo en su diseño:

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

Y finalmente comenzando la animación:

Circle circle = (Circle) findViewById(R.id.circle); CircleAngleAnimation animation = new CircleAngleAnimation(circle, 240); animation.setDuration(1000); circle.startAnimation(animation);

El resultado es: