圆环形TextView+旋转动画

效果图

备注:效果是四个自定义的CircleTextView设置不同的旋转方向、速度、透明度居中对齐的最终效果。

旋转TextView

实现原理:

1、绘制圆环形路径TextView
private void drawCircleText(Canvas canvas) {

    Path path = new Path();
    path.addCircle(centerX, centerY, radius, Path.Direction.CW);
    canvas.drawTextOnPath(getText().toString(), path, 0, 0, paint);
}
2、设置rotation属性动画
public void doAnimation() {

    if (rotationCM)
        animator = ObjectAnimator.ofFloat(this, "rotation", 0f, 360f);
    else
        animator = ObjectAnimator.ofFloat(this, "rotation", 360f, 0f);

    animator.setDuration(rotationTime);
    animator.setRepeatMode(ValueAnimator.RESTART);
    animator.setRepeatCount(ValueAnimator.INFINITE);
    animator.setInterpolator(new LinearInterpolator());
    animator.start();
}
3、备注:自定义的xml属性,诸如:旋转方向、文字透明度、旋转一圈用时…请见详细代码

详细代码

1、自定义CircleTextView代码
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.text.Layout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
import android.widget.TextView;

import com.example.zpf.animmenu.R;

/**
 * Created by zpf on 2016/11/9.
 * 圆形路径旋转文字
 */
public class CircleTextView extends TextView {


    /**
     * 默认文字透明度
     */
    private final int DEFAULT_ALPHA = 120;

    /**
     * 默认的旋转一周的时间
     */
    private final int DEFAULT_ROTATION_TIME = 4000;
    /**
     * 文字旋转中心点坐标
     */
    private float centerX, centerY;

    /**
     * 根据控件长宽测量的半径
     */
    private float radius;

    /**
     * 文字画笔
     */
    private TextPaint paint;

    /**
     * text alpha
     */
    private int alpha = DEFAULT_ALPHA;

    /**
     * 是否顺时针旋转(默认逆时针)
     */
    private boolean rotationCM = false;

    /**
     * 旋转一圈的时间
     */
    private int rotationTime = DEFAULT_ROTATION_TIME;

    private ObjectAnimator animator;

    public CircleTextView(Context context) {
        super(context);
    }

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

        initDefineAttr(context, attrs);
        initPaint();
    }

    public CircleTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initDefineAttr(context, attrs);
        initPaint();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        radius = Math.min(w, h) / 2 - getTextSize();
        centerX = w / 2;
        centerY = h / 2;

        super.onSizeChanged(w, h, oldw, oldh);
    }

    private void initDefineAttr(Context context, AttributeSet attrs) {

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleTextView);
        int count = array.getIndexCount();

        for (int i = 0; i < count; i++) {

            int attr = array.getIndex(i);

            switch (attr) {

                case R.styleable.CircleTextView_circleTextAlpha:

                    alpha = array.getInt(attr, DEFAULT_ALPHA);
                    if (alpha < 0 || alpha > 255)
                        alpha = DEFAULT_ALPHA;
                    break;

                case R.styleable.CircleTextView_circleRotationCW:

                    rotationCM = array.getBoolean(attr, false);
                    break;

                case R.styleable.CircleTextView_circleRotationTime:

                    rotationTime = array.getInt(attr, DEFAULT_ROTATION_TIME);
                    break;

                default:
                    break;
            }
        }

        array.recycle();
    }

    /**
     * init Paint
     */
    private void initPaint() {

        paint = new TextPaint();
        paint.setAntiAlias(true);
        paint.setColor(getCurrentTextColor());
        paint.setStyle(Paint.Style.FILL);
        paint.setTextSize(getTextSize());
        paint.setAlpha(alpha);

        //文本渐变
//        float textWidth = paint.measureText(getText().toString());
//        Shader shader = new LinearGradient(0, 0, textWidth, 0, Color.TRANSPARENT,
//                getCurrentTextColor(), Shader.TileMode.CLAMP);
//        paint.setShader(shader);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawCircleText(canvas);
    }

    /**
     * draw circle text
     */
    private void drawCircleText(Canvas canvas) {

        Path path = new Path();
        path.addCircle(centerX, centerY, radius, Path.Direction.CW);
        canvas.drawTextOnPath(getText().toString(), path, 0, 0, paint);
    }

    public void doAnimation() {

        if (rotationCM)
            animator = ObjectAnimator.ofFloat(this, "rotation", 0f, 360f);
        else
            animator = ObjectAnimator.ofFloat(this, "rotation", 360f, 0f);

        animator.setDuration(rotationTime);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }

    public void cancelAnimation() {

        animator.cancel();
    }
}
2、用到的自定义属性的attrs.xml内部的样式表declare-styleable声明
<!-- CircleTextView -->
    <declare-styleable name="CircleTextView">
        <!-- 文本透明度(0-255,数值越小越透明) -->
        <attr name="circleTextAlpha" format="integer" />

        <!-- 顺时针旋转文字 -->
        <attr name="circleRotationCW" format="boolean" />

        <!-- 旋转文字一圈的时间(毫秒) -->
        <attr name="circleRotationTime" format="integer" />
    </declare-styleable>
3、xml布局文件当中引用
<customview.CircleTextView
                android:id="@+id/ctv_one"
                android:layout_centerInParent="true"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:text="殷疑曙霞染,巧类匣刀裁"
                android:textColor="@color/colorWhite"
                android:textSize="12sp"
                app:circleTextAlpha="60"
                app:circleRotationCW="true"
                app:circleRotationTime="4000"/>

备注:
a、app:circleTextAlpha=“integer”为文字透明度,取值[0-255]
b、app:circleRotationCW=”boolean” 为是否为顺时针旋转
c、app:circleRotationTime=“long”为旋转一周用时,单位毫秒

4、activity中启动动画使用
//启动动画:调用CircleTextView的
doAnimation();

//取消动画:调用CircleTextView的
CircleTextView.cancelAnimation();
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值