太极图
2018-03-21 本文已影响23人
有点健忘
先看下效果

简单说起来就是几个圆或者半圆组合起来就是拉。
就是说外边一个大圆,然后中心y轴上有2个半圆,分别取一半,至于两个鱼眼也在这个y轴上,鱼眼半径我们就取大圆半径的1/6吧
下边就是代码了,简单说明下,黑白两条鱼就用path来画的。都是拼接3个半圆的线条完成的。
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
/**太极图就是外边一个大圆,中心线上两个小圆各取一半组成的*/
public class TaiJiView extends View {
public TaiJiView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private void initPaint() {
paint.setStyle(Style.FILL);
}
private int radius;// 太极的半径,我们取宽高最小值的2/3
private Path pathLeft = new Path();// 太极左边的路径
private Path pathRight = new Path();// 右边的路径
RectF oval = new RectF();//大圆的范围
RectF ovalTop = new RectF();//上边小圆的
RectF ovalBottom = new RectF();//下边小圆的范围
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
radius = (Math.min(getMeasuredWidth(), getMeasuredHeight()) * 2 / 3) >> 1;
if (radius > 0) {
pathLeft.reset();
//下边的坐标计算都是把中心点偏移到画布正中心来计算的
oval.set(-radius, -radius, radius, radius);
ovalTop.set(-radius / 2, -radius, radius / 2, 0);
ovalBottom.set(-radius / 2, 0, radius / 2, radius);
pathLeft.addArc(oval, 90, 180);
pathLeft.addArc(ovalTop, -90, 180);
pathLeft.addArc(ovalBottom, 90, 180);
pathRight.addArc(oval, 90, -180);
pathRight.addArc(ovalTop, -90, 180);
pathRight.addArc(ovalBottom, 90, 180);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (radius == 0) {
return;
}
canvas.save();
canvas.translate(getWidth() >> 1, getHeight() >> 1);
canvas.rotate(degress,0,0);
paint.setColor(Color.WHITE);
canvas.drawPath(pathLeft, paint);
paint.setColor(Color.BLACK);
canvas.drawPath(pathRight, paint);
//画两个太极眼, 这里坐标点其实不用算,就是在y轴上,最开始我是偏移了一定角度的才这样写的
canvas.drawCircle(0,-radius/2, radius / 6, paint);
paint.setColor(Color.WHITE);
canvas.drawCircle(0,radius/2,radius / 6, paint);
// canvas.drawCircle((float) (radius / 2f * Math.cos(-Math.PI / 2)),
// (float) (radius / 2f * Math.sin(-Math.PI / 2)), radius / 6, paint);
// paint.setColor(Color.WHITE);
// canvas.drawCircle((float) (radius / 2f * Math.cos(Math.PI / 2)), (float) (radius / 2f * Math.sin(Math.PI / 2)),
// radius / 6, paint);
canvas.restore();
}
float degress=0;
ValueAnimator animator;
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if(animator==null) {
animator=ValueAnimator.ofFloat(0,360);
animator.setDuration(5000);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
degress=(Float) animation.getAnimatedValue();
postInvalidate();
}
});
animator.start();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if(animator!=null) {
animator.cancel();
animator=null;
}
}
}
上边最后简单了加了下旋转动画,其实不需要的可以不要,也可以在代码里通过位旋转动画来实现
TaiJiView taiJiView=(TaiJiView) findViewById(R.id.taiJiView1);
RotateAnimation rotateAnimation=new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(2000);
rotateAnimation.setRepeatCount(2);
taiJiView.startAnimation(rotateAnimation);
一个简单的八卦图就完工了。