===================================================================
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
useWidth = mWidth;
if (mWidth > mHeight) {
useWidth = mHeight;
}
}
将布局分为10份。以minwidth的1,3,5,7,9的倍数为标准点。
minwidth = useWidth / 10;
=========================================================================
mPaint = new Paint(); //创建画笔对象
mPaint.setColor(Color.BLACK); //设置画笔颜色
mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
mPaint.setStrokeWidth(4f); //设置画笔宽度为10px
mPaint.setAntiAlias(true); //设置抗锯齿
mPaint.setAlpha(255); //设置画笔透明度
//细的X轴
canvas.drawLine(minwidth, 3 * minwidth, 9 * minwidth, 3 * minwidth, mPaint);// 斜线
canvas.drawLine(minwidth, 5 * minwidth, 9 * minwidth, 5 * minwidth, mPaint);// 斜线
canvas.drawLine(minwidth, 7 * minwidth, 9 * minwidth, 7 * minwidth, mPaint);// 斜线
//细的y轴
canvas.drawLine(3 * minwidth, minwidth, 3 * minwidth, 9 * minwidth, mPaint);// 斜线
canvas.drawLine(5 * minwidth, minwidth, 5 * minwidth, 9 * minwidth, mPaint);// 斜线
canvas.drawLine(7 * minwidth, minwidth, 7 * minwidth, 9 * minwidth, mPaint);// 斜线
mPaint.setStrokeWidth(8f);
//粗的X轴(边框)
canvas.drawLine(minwidth, minwidth, 9 * minwidth, minwidth, mPaint);// 斜线
canvas.drawLine(minwidth, 9 * minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线
//粗的y轴(边框)
canvas.drawLine(minwidth, minwidth, minwidth, 9 * minwidth, mPaint);// 斜线
canvas.drawLine(9 * minwidth, minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线
绘制完后,发现有点小瑕疵
效果图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201230150648950.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 开源分享
text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyNzYxMzk1,size_16,color_FFFFFF,t_70)
canvas.drawPoint(minwidth, minwidth, mPaint);
canvas.drawPoint(9 * minwidth, minwidth, mPaint);
canvas.drawPoint(minwidth, 9 * minwidth, mPaint);
canvas.drawPoint(9 * minwidth, 9 * minwidth, mPaint);
效果图:
=======================================================================================
位置比例
(3,3)(3,5)(3,7)
(5,3)(5,5)(5,7)
(7,3)(7,5)(7,7)
//画围棋
canvas.drawCircle(3minwidth, 3minwidth, useWidth/16, mPaint);
canvas.drawCircle(3minwidth, 7minwidth, useWidth/16, mPaint);
canvas.drawCircle(5minwidth, 5minwidth, useWidth/16, mPaint);
canvas.drawCircle(7minwidth, 3minwidth, useWidth/16, mPaint);
canvas.drawCircle(7minwidth, 7minwidth, useWidth/16, mPaint);
mPaint.setColor(rightcolor);
canvas.drawCircle(3minwidth, 5minwidth, useWidth/16, mPaint);
canvas.drawCircle(5minwidth, 3minwidth, useWidth/16, mPaint);
canvas.drawCircle(5minwidth, 7minwidth, useWidth/16, mPaint);
canvas.drawCircle(7minwidth, 5minwidth, useWidth/16, mPaint);
效果图:
=============================================================================
1.三个辅助类为动画做准备(参数模仿Android官方Demo)
主要为get set构造,代码会贴到最后
public class XYEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
XYHolder startXY = (XYHolder) startValue;
XYHolder endXY = (XYHolder) endValue;
return new XYHolder(startXY.getX() + fraction * (endXY.getX() - startXY.getX()),
startXY.getY() + fraction * (endXY.getY() - startXY.getY()));
}
}
private ShapeHolder createBall(float x, float y, int color) {
OvalShape circle = new OvalShape();
circle.resize(useWidth / 8f, useWidth / 8f);
ShapeDrawable drawable = new ShapeDrawable(circle);
ShapeHolder shapeHolder = new ShapeHolder(drawable);
shapeHolder.setX(x - useWidth / 16f);
shapeHolder.setY(y - useWidth / 16f);
Paint paint = drawable.getPaint();
paint.setColor(color);
return shapeHolder;
}
private void createAnimation() {
if (bounceAnim == null) {
XYHolder lstartXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
XYHolder processXY = new XYHolder(7 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
XYHolder lendXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
bounceAnim = ObjectAnimator.ofObject(ballHolder, “xY”,
new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
bounceAnim.setDuration(animaltime);
bounceAnim.setRepeatCount(ObjectAnimator.INFINITE);
bounceAnim.setRepeatMode(ObjectAnimator.RESTART);
bounceAnim.addUpdateListener(this);
}
if (bounceAnim1 == null) {
XYHolder lstartXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
XYHolder processXY = new XYHolder(3 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
XYHolder lendXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
bounceAnim1 = ObjectAnimator.ofObject(ballHolder1, “xY”,
new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
bounceAnim1.setDuration(animaltime);
bounceAnim1.setRepeatCount(ObjectAnimator.INFINITE);
bounceAnim1.setRepeatMode(ObjectAnimator.RESTART);
bounceAnim1.addUpdateListener(this);
}
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bounceAnim).with(bounceAnim1);
animatorSet.start();
视觉效果:感觉白子不太明显
在棋子的创建方法中添加渐变色
RadialGradient gradient = new RadialGradient(useWidth / 16f, useWidth / 16f,
useWidth / 8f, color, Color.GRAY, Shader.TileMode.CLAMP);
paint.setShader(gradient);
shapeHolder.setPaint(paint);
效果图:
======================================================================
attrs文件:
java文件中获取
/**
- 获取自定义属性
*/
private void initCustomAttrs(Context context, AttributeSet attrs) {
//获取自定义属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.WeiqiView);
//获取颜色
leftcolor = ta.getColor(R.styleable.WeiqiView_leftscolor, Color.BLACK);
rightcolor = ta.getColor(R.styleable.WeiqiView_rightscolor, Color.WHITE);
qipancolor = ta.getColor(R.styleable.WeiqiView_qipancolor, Color.BLACK);
//获取动画时间
animaltime = ta.getInt(R.styleable.WeiqiView_animalstime, 2000);
//回收
ta.recycle();
}
=============================================================================
===============================================================================
然后,把背景注释,像不像那些等待动画?
===================================================================
WeiqiView.java
public class WeiqiView extends View implements ValueAnimator.AnimatorUpdateListener {
private Paint mPaint;
private int mWidth;
private int mHeight;
private int useWidth, minwidth;
private int leftcolor;
private int rightcolor;
private int qipancolor;
private int animaltime;
//画一个圆(棋子)
ValueAnimator bounceAnim, bounceAnim1 = null;
ShapeHolder ball, ball1 = null;
QiziXYHolder ballHolder, ballHolder1 = null;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public WeiqiView(Context context) {
this(context, null);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public WeiqiView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public WeiqiView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
initCustomAttrs(context, attrs);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public WeiqiView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private void init() {
initPaint();
}
/**
- 获取自定义属性
*/
private void initCustomAttrs(Context context, AttributeSet attrs) {
//获取自定义属性。
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.WeiqiView);
//获取颜色
leftcolor = ta.getColor(R.styleable.WeiqiView_leftscolor, Color.BLACK);
rightcolor = ta.getColor(R.styleable.WeiqiView_rightscolor, Color.WHITE);
qipancolor = ta.getColor(R.styleable.WeiqiView_qipancolor, Color.BLACK);
animaltime = ta.getInt(R.styleable.WeiqiView_animalstime, 2000);
//回收
ta.recycle();
}
/**
- 初始化画笔
*/
private void initPaint() {
mPaint = new Paint(); //创建画笔对象
mPaint.setColor(Color.BLACK); //设置画笔颜色
mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
mPaint.setStrokeWidth(4f); //设置画笔宽度为10px
mPaint.setAntiAlias(true); //设置抗锯齿
mPaint.setAlpha(255); //设置画笔透明度
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
useWidth = mWidth;
if (mWidth > mHeight) {
useWidth = mHeight;
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
init();
minwidth = useWidth / 10;
mPaint.setColor(qipancolor);
if (ball == null) {
ball = createBall(3 * minwidth, 3 * minwidth, leftcolor);
ballHolder = new QiziXYHolder(ball);
}
if (ball1 == null) {
ball1 = createBall(7 * minwidth, 7 * minwidth, rightcolor);
ballHolder1 = new QiziXYHolder(ball1);
}
//细的X轴
canvas.drawLine(minwidth, 3 * minwidth, 9 * minwidth, 3 * minwidth, mPaint);// 斜线
canvas.drawLine(minwidth, 5 * minwidth, 9 * minwidth, 5 * minwidth, mPaint);// 斜线
canvas.drawLine(minwidth, 7 * minwidth, 9 * minwidth, 7 * minwidth, mPaint);// 斜线
//细的y轴
canvas.drawLine(3 * minwidth, minwidth, 3 * minwidth, 9 * minwidth, mPaint);// 斜线
canvas.drawLine(5 * minwidth, minwidth, 5 * minwidth, 9 * minwidth, mPaint);// 斜线
canvas.drawLine(7 * minwidth, minwidth, 7 * minwidth, 9 * minwidth, mPaint);// 斜线
mPaint.setStrokeWidth(8f);
//粗的X轴(边框)
canvas.drawLine(minwidth, minwidth, 9 * minwidth, minwidth, mPaint);// 斜线
canvas.drawLine(minwidth, 9 * minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线
//粗的y轴(边框)
canvas.drawLine(minwidth, minwidth, minwidth, 9 * minwidth, mPaint);// 斜线
canvas.drawLine(9 * minwidth, minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线
//补瑕疵
canvas.drawPoint(minwidth, minwidth, mPaint);
canvas.drawPoint(9 * minwidth, minwidth, mPaint);
canvas.drawPoint(minwidth, 9 * minwidth, mPaint);
canvas.drawPoint(9 * minwidth, 9 * minwidth, mPaint);
// //画围棋
// canvas.drawCircle(3minwidth, 3minwidth, useWidth/16, mPaint);
// canvas.drawCircle(3minwidth, 7minwidth, useWidth/16, mPaint);
// canvas.drawCircle(5minwidth, 5minwidth, useWidth/16, mPaint);
// canvas.drawCircle(7minwidth, 3minwidth, useWidth/16, mPaint);
// canvas.drawCircle(7minwidth, 7minwidth, useWidth/16, mPaint);
// mPaint.setColor(rightcolor);
// canvas.drawCircle(3minwidth, 5minwidth, useWidth/16, mPaint);
// canvas.drawCircle(5minwidth, 3minwidth, useWidth/16, mPaint);
// canvas.drawCircle(5minwidth, 7minwidth, useWidth/16, mPaint);
// canvas.drawCircle(7minwidth, 5minwidth, useWidth/16, mPaint);
canvas.save();
canvas.translate(ball.getX(), ball.getY());
ball.getShape().draw(canvas);
canvas.restore();
canvas.save();
canvas.translate(ball1.getX(), ball1.getY());
ball1.getShape().draw(canvas);
canvas.restore();
}
private ShapeHolder createBall(float x, float y, int color) {
OvalShape circle = new OvalShape();
circle.resize(useWidth / 8f, useWidth / 8f);
ShapeDrawable drawable = new ShapeDrawable(circle);
ShapeHolder shapeHolder = new ShapeHolder(drawable);
shapeHolder.setX(x - useWidth / 16f);
shapeHolder.setY(y - useWidth / 16f);
Paint paint = drawable.getPaint();
paint.setColor(color);
RadialGradient gradient = new RadialGradient(useWidth / 16f, useWidth / 16f,
useWidth / 8f, color, Color.GRAY, Shader.TileMode.CLAMP);
paint.setShader(gradient);
shapeHolder.setPaint(paint);
return shapeHolder;
}
private void createAnimation() {
if (bounceAnim == null) {
XYHolder lstartXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
XYHolder processXY = new XYHolder(7 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
XYHolder lendXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
bounceAnim = ObjectAnimator.ofObject(ballHolder, “xY”,
new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
bounceAnim.setDuration(animaltime);
bounceAnim.setRepeatCount(ObjectAnimator.INFINITE);
bounceAnim.setRepeatMode(ObjectAnimator.RESTART);
bounceAnim.addUpdateListener(this);
}
if (bounceAnim1 == null) {
XYHolder lstartXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
XYHolder processXY = new XYHolder(3 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
XYHolder lendXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
bounceAnim1 = ObjectAnimator.ofObject(ballHolder1, “xY”,
new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
bounceAnim1.setDuration(animaltime);
bounceAnim1.setRepeatCount(ObjectAnimator.INFINITE);
bounceAnim1.setRepeatMode(ObjectAnimator.RESTART);
bounceAnim1.addUpdateListener(this);
}
}
public void startAnimation() {
createAnimation();
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bounceAnim).with(bounceAnim1);
animatorSet.start();
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
invalidate();
}
}
QiziXYHolder.java
public class QiziXYHolder {
private ShapeHolder mBall;
public QiziXYHolder(ShapeHolder ball) {
mBall = ball;
}
public void setXY(XYHolder xyHolder) {
mBall.setX(xyHolder.getX());
mBall.setY(xyHolder.getY());
}
public XYHolder getXY() {
return new XYHolder(mBall.getX(), mBall.getY());
}
}
ShapeHolder.java
public class ShapeHolder {
private float x = 0, y = 0;
private ShapeDrawable shape;
private int color;
private RadialGradient gradient;
private float alpha = 1f;