Android自定义view之围棋动画,真牛皮
@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;
}
}
2.定义测量最小长度
将布局分为10份。以minwidth的1,3,5,7,9的倍数为标准点。
minwidth = useWidth / 10;
二、绘制背景(棋盘)
=========================================================================
1.初始化画笔
mPaint = new Paint(); //创建画笔对象
mPaint.setColor(Color.BLACK); //设置画笔颜色
mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
mPaint.setStrokeWidth(4f); //设置画笔宽度为10px
mPaint.setAntiAlias(true); //设置抗锯齿
mPaint.setAlpha(255); //设置画笔透明度
2.画棋盘
//细的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);// 斜线
绘制完后,发现有点小瑕疵
效果图:
3.补棋盘瑕疵
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构造,代码会贴到最后
2.自定义该接口实例来控制动画的更新计算表达式
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()));
}
}
3.棋子的创建
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;
}
4.动画的创建
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);
}
}
5.两个动画的同步执行
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bounceAnim).with(bounceAnim1);
animatorSet.start();
6.效果图
视觉效果:感觉白子不太明显
7.解决第6步问题
在棋子的创建方法中添加渐变色
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);
最后
最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2020-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,这里我也免费分享给大家也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
有需要的朋友可以点击:**Android面试资料**免费领取~
一起互勉~
dth - 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);
最后
最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2020-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,这里我也免费分享给大家也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
有需要的朋友可以点击:**Android面试资料**免费领取~
[外链图片转存中…(img-UsukI5Ke-1646227508556)]
[外链图片转存中…(img-5DR4M6IY-1646227508557)]
一起互勉~
Android自定义view之围棋动画,真牛皮相关推荐
- Android自定义view之围棋动画
Android自定义view之围棋动画 好久不见,最近公众号内粉丝要求上新一篇有点难度的自定义view文章,所以它来了!! 干货文,建议收藏 文章目录 Android自定义view之围棋动画 前言 完 ...
- android view 渐变动画,Android自定义view渐变圆形动画
本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...
- android 自定义加载动画效果,Android自定义View实现loading动画加载效果
项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. ...
- Android 自定义View之咖啡杯动画
效果 大概思路 自定义view,直接继承view 复写onSizeChanged()方法,在此计算杯垫,杯子,烟雾效果的path 在onDraw()方法中,描绘杯垫,杯子 处理烟雾动画效果 画杯子 这 ...
- android下雨动画效果,Android 自定义View之下雨动画
开始前先做个热身( ˘•灬•˘ ) 自己实现比较容易,但是到了要出博客整理思路,总结要点的时候就挠头,不知云所以,所以最简单的还是 如果对安卓UI有兴趣的朋友可以加我好友互相探讨, 思路 思路比较简单 ...
- android自定义view之星星动画
先上效果图 其实上边效果分为几个部分,一个部分是多个小星星四处扩散,第二个部分是一个小星星从小变大,还有一个是实心圆的动画. 代码如下 第一:所有的小星星动画 public class StarVie ...
- 一篇文章带你走近Android自定义view
系列文章目录 一篇文章带你走近Android自定义view 文章目录 系列文章目录 前言 一.为什么要自定义view 二.先看看一个超级简单的自定义view(三个构造函数) 三.了解手机的坐标系 四. ...
- android刷新时的圆形动画_Android自定义view渐变圆形动画
本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...
- android录音波浪动画_Android自定义View实现波浪动画
本文实例为大家分享了Android自定义View实现波浪动画的具体代码,供大家参考,具体内容如下 效果演示 代码调用与实现效果 xml中调用 android:layout_width="ma ...
最新文章
- 云原生思想 — 云原生应用
- Python Split函数的用法总结
- Boost:glob测试程序
- Spring boot的简单用法
- node截图服务可用性报告
- “啁啾”看完这篇再不懂,放弃吧……
- IOS --xcode删除Provisioning Profiles文件
- 【2018蓝桥省赛A组C/C++】倍数问题(dp+滚动数组)
- linux 卸载java jdk1.6_Linux 下安装与卸载JDK(jdk-6u16-)
- DELL服务器安装centos系统
- Excel怎么将不规律的英文字母提取出来
- IP地址的分类及范围详解:A、B、C、D、E五类是如何划分的
- Vue 使用 Apache Echarts 绘制地图(省市、地区)
- 最全最新cpu显卡天梯图_2019桌面级显卡排行_2019年2月最新CPU天梯图 桌面级处理器天梯图...
- Ubuntu10.10下安装Tor,PolipoVidalia
- Python爬虫进阶之爬取篮球赛数据
- 从0开始学习 GitHub 系列之「05.Git 进阶」----转载自stormzhang 原创文章
- 你到底要一台什么样的笔记本
- Django 基于类的通用视图详解
- 零基础转行,入职军工类测试方向,月薪10K | 既然选择了,就要全力以赴
热门文章
- Android高仿微信头像裁剪
- 用友显示用友通服务器,用友T3用友通无法连接服务器--用友T3用友通无法连接服务器...
- nvme分区选mbr还是guid_怎么分辨硬盘是GUID格式还是MBR格式以及怎样更改
- 凭软考中高级证书可抵扣个税3600元,12月31日前记得做
- VIP网易邮箱,163VIP邮箱,新浪vip等邮箱的对比分析
- h5使用js的点击复制功能,兼容安卓和ios,亲测有效
- 鼠标悬停帮助图标显示文字提示框代码
- Java毕业设计项目_企业级实战全栈项目中信CRM
- PHP 调用浏览器下载文件
- 闭式系统蒸汽管径推荐速度_暖通设计常用参考数据1