首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在android中使用动画绘制基于值的圆大小的圆

问如何在android中使用动画绘制基于值的圆大小的圆
EN

Stack Overflow用户
提问于 2015-04-01 09:40:52
回答 3查看 40.8K关注 0票数 60

我想开发一个自定义组件,绘制基于不同值的圆的一部分。如绘制1/4圆、1/2圆等,需要对构件进行动画处理以显示绘制过程。部分圆是在静态图像视图上绘制的,我计划使用两个视图,一个动画视图在静态视图之上。有什么建议如何开发它吗?

我把截图放在这里作为参考。

​

​

请参考这张图片,并感受一下它的样子。谢谢!

提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-01 10:18:44

您必须绘制圆形视图,然后应为其创建动画。

创建圆形视图:

代码语言:javascript
复制
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;
    }
}

创建动画类以设置新角度:

代码语言:javascript
复制
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();
    }
}

将圆圈放入布局中:

代码语言:javascript
复制
<com.package.Circle
    android:id="@+id/circle"
    android:layout_width="300dp"
    android:layout_height="300dp" />

最后开始播放动画:

代码语言:javascript
复制
Circle circle = (Circle) findViewById(R.id.circle);

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

结果是:

​

票数 144
EN

Stack Overflow用户

发布于 2018-01-29 18:51:10

来自@JohnCordeiro answer的额外回复。我已经从xml中添加了参数,以重用圆,并在需要时填充圆。

代码语言:javascript
复制
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)
}
}

在xml上:

代码语言:javascript
复制
        <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" />

结果如下:注意按钮的半透明填充

​

​

票数 3
EN

Stack Overflow用户

发布于 2019-04-05 15:00:54

添加了用于计算正确圆测量值的代码

代码语言:javascript
复制
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)
    }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29381474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档