Android实现立体圆柱控件,Android 酷炫的3d立体圆柱动画效果实现_移动开发_化身孤岛的瓜...
然后准备实现一波,做之前在网上找了很久,并没有相似的效果,所以自己做了一个,已经上传到我的代码库里:
欢迎小伙伴们的start或者requests
下面简单说一下实现过程:
1.首先要讲传入的数据数组进行排序,因为是2d平面模拟3d,所以弧形的绘制要由内到外才不会出现错位的情况:
//计算出绘制顺序
private void computationOrder(){
ArrayList tempOrderList = new ArrayList<>();
leftAngle = 0;
rightAngle = 0;
for (int i = 0; i < max; i++) {
Collections.sort(mEntries, new MyCompare());
Entry tempEntry = mEntries.get(0);
float halfAngle = tempEntry.percent / 2;
/*
1.算法,先绘制最大的一块,居中
2.剩下的 优先记录左边和右边的坐标值
3.优先添加不会溢出的
*/
if (i == 0) {
leftAngle = 270f - halfAngle;
rightAngle = 270f + halfAngle;
if (rightAngle >= 360) {
rightAngle -= 360f;
}
tempEntry.tag = CENTER;
tempEntry.startAngle = leftAngle;
mEntries.remove(0);
} else {
//1.找到当前小的边
if (getDistanceToCenter(leftAngle, LEFT) > getDistanceToCenter(rightAngle, RIGHT)) {
//左边比右边大,取右边
tempEntry = getNextAngle(getDistanceToCenter(rightAngle, RIGHT));
tempEntry.tag = RIGHT;
rightAngle += tempEntry.percent;
if (rightAngle >= 360) {
rightAngle -= 360f;
}
tempEntry.startAngle = rightAngle;
} else {
//右边比左边大,取左边
tempEntry = getNextAngle(getDistanceToCenter(leftAngle, LEFT));
tempEntry.tag = LEFT;
leftAngle -= tempEntry.percent;
tempEntry.startAngle = leftAngle;
}
}
tempOrderList.add(tempEntry);
}
mEntrySourceList = tempOrderList;
}
2.然后是绘制部分,首先根据排列的顺序进行绘制,依次绘制各个弧形段,然后画轮廓线:
private void drawCylinder(Canvas canvas, Entry tempEntry, int thickness,boolean ifChangeThick){
mainPaint.setStyle(Paint.Style.FILL);
//绘制各个弧度
int perThickness =ifChangeThick? (int) ((tempEntry.percent / 360f) * thickness * (max * 0.5f)) : thickness;
float drawTempStartAngle = 0f;
RectF tempRectF;
float lineStartX = 0f;
float lineStartY = 0f;
float lineEndX = 0f;
float lineEndY = 0f;
float oX = centerX;
float oY = (area2DHeight + area3DHight) / 2;
float R = centerX;
//y轴2d3d缩放比例
float bilv = ((float) (area3DHight - area2DHeight)) / ((float) area2DHeight);
for (int j = 0; j <= perThickness; j++) {
tempRectF = new RectF(0, area2DHeight - j, area2DWidth, area3DHight - j);
switch (tempEntry.tag) {
case CENTER:
drawTempStartAngle = tempEntry.startAngle;
lineStartX = oX;
lineEndX = oX;
lineStartY = (area2DHeight + area3DHight) / 2;
lineEndY = oY - j;
break;
case LEFT:
drawTempStartAngle = tempEntry.startAngle;
/*
左边夹角tempAngle 0< tempAngle < 180
90
*/
if (drawTempStartAngle <= 180) {
//startAngle 90-180
lineStartX = oX - (float) (R * Math.sin(Math.toRadians(drawTempStartAngle - 90f)));
lineEndX = lineStartX;
lineStartY = oY + (float) (bilv * R * Math.cos(Math.toRadians(drawTempStartAngle - 90f)));
lineEndY = lineStartY - j;
} else {
//startAngle 180-270
lineStartX = oX - (float) (R * Math.cos(Math.toRadians(drawTempStartAngle - 180f)));
lineEndX = lineStartX;
lineStartY = oY - (float) (bilv * R * Math.sin(Math.toRadians(drawTempStartAngle - 180f)));
lineEndY = lineStartY - j;
}
break;
case RIGHT:
drawTempStartAngle = tempEntry.startAngle - tempEntry.percent;
/*
右边夹角tempAngle 0< tempAngle < 180
90
*/
if (drawTempStartAngle <= 360) {
//startAngle 270-360
lineStartX = oX + (float) (R * Math.cos(Math.toRadians(360f - drawTempStartAngle - tempEntry.percent)));
lineEndX = lineStartX;
lineStartY = oY - (float) (bilv * R * Math.sin(Math.toRadians(360f - drawTempStartAngle - tempEntry.percent)));
lineEndY = lineStartY - j;
} else {
//startAngle 0-90
lineStartX = oX + (float) (R * Math.cos(Math.toRadians(drawTempStartAngle)));
lineEndX = lineStartX;
lineStartY = oY - (float) (bilv * R * Math.sin(Math.toRadians(drawTempStartAngle)));
lineEndY = lineStartY - j;
}
break;
}
//弧形
mainPaint.setColor(tempEntry.color);
canvas.drawArc(tempRectF, drawTempStartAngle, tempEntry.percent, true, mainPaint);
if (j == perThickness) {
drawTopLine(canvas, tempRectF, drawTempStartAngle, tempEntry.percent);
}
//竖直线
mainPaint.setColor(Color.WHITE);
if (tempEntry.tag == CENTER) {
canvas.drawLine(lineStartX, lineStartY,
lineEndX, lineEndY,
mainPaint);
//还需要画左右两边的竖直线
float xOffset = (float) (R * Math.sin(Math.toRadians(tempEntry.percent / 2)));
float yOffset = (float) (bilv * R * Math.cos(Math.toRadians(tempEntry.percent / 2)));
canvas.drawLine(
oX - xOffset,
oY - yOffset,
oX - xOffset,
oY - yOffset - j,
mainPaint);
canvas.drawLine(
oX + xOffset,
oY - yOffset,
oX + xOffset,
oY - yOffset - j,
mainPaint);
} else {
canvas.drawLine(lineStartX, lineStartY,
lineEndX, lineEndY,
mainPaint);
}
}
}
3.两种不同的动画效果在ondraw里面分别进行判断:
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
switch (ANIM_STATE) {
case ANIM_STATE_ALL:
for (int i = 0; i < mEntrySourceList.size(); i++) {
Entry tempEntry = mEntrySourceList.get(i);
drawCylinder(canvas, tempEntry, thickness,true);
}
break;
case ANIM_STATE_SINGLE:
for (int i = 0; i < mEntrySourceList.size(); i++) {
Entry tempEntry = mEntrySourceList.get(i);
drawCylinder(canvas, tempEntry, 1,false);
}
for (int i = 0; i < singleAnimIndex; i++) {
if (i < mEntrySourceList.size()) {
Entry tempEntry = mEntrySourceList.get(i);
int tempThickNess = singleAnimValue - (i + 1) * 100;
LogUtils.INSTANCE.d("tempThickNess: " + tempThickNess);
tempThickNess = (int) ((tempEntry.percent / 360f) * tempThickNess * (max * 0.33f));
drawCylinder(canvas, tempEntry, tempThickNess,false);
}
}
break;
case ANIM_STATE_CHANGGE:
break;
}
}
至此就介绍得差不多了,具体的代码里面都有注释,希望喜欢的小伙伴们点个赞,有问题可以留言。
Android实现立体圆柱控件,Android 酷炫的3d立体圆柱动画效果实现_移动开发_化身孤岛的瓜...相关推荐
- 视频教程-Android Material Design 新控件-Android
Android Material Design 新控件 刘志远,北京邮电大学硕士研究生, 北京育华志远科技有限公司创始人, 育华志远教育品牌负责人,育华志远课程体系打造者. 率领团队为互联网行业培训千 ...
- Android之——史上最简单最酷炫的3D图片浏览效果的实现
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48052709 如今,Android开发已经成为移动互联开发领域中一支不可或缺的力量 ...
- Android 酷炫的3d立体圆柱动画效果实现
最近在drrible上看到一个超酷炫的效果,立体圆柱缓慢上升:https://dribbble.com/shots/7077455-Spending-analytics 然后准备实现一波,做之前在网上 ...
- android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...
转载:http://blog.csdn.net/xiabing082/article/details/48781489 1. 大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...
- android点击隐藏控件,Android编程实现点击EditText之外的控件隐藏软键盘功能
本文实例讲述了Android编程实现点击EditText之外的控件隐藏软键盘功能.分享给大家供大家参考,具体如下: 工具类 ... public static void hideKeyboard(Co ...
- android中互斥的控件,Android控件之Radiobutton与RadioGroup
RadioButton 是一个单选控件,在一个RadioGroup中,各个RadioButton是互斥的 XML文件: xmlns:tools="http://schemas.android ...
- android自定义选年控件,Android精美日历控件CalendarView自定义使用完全解析
项目github地址 此框架采用组合的方式,各个模块互相独立,可自由采用各种提供的控件组合,完全自定义自己需要的UI,周视图和月视图可通过简单自定义任意自由绘制,不怕美工提需求!!!下面教程将介绍如何 ...
- android 除了webview 浏览器控件,android开发我的新浪微博客户端-OAuth认证过程中用WebView代替原来的系统自带浏览器...
前面的文章的OAuth认证过程在获取oauth_verifier码是是通过调用android系统带的浏览器进行用户授权认证的, 具体见:android开发我的新浪微博客户端-用户授权页面功能篇(3.2 ...
- android bind 自动声明控件,Android注解神器ButterKnife使用说明
阅读本文大概需要5分钟 前言 如果你还在一行一行的手写findViewById的话,只能证明你对新技术的敏感度太差,间接地暴露了你不善于接受新事物的性格特征,太过于因循守旧.按部就班,这对于一个程序员 ...
- android中翻页控件,Android GridView控件分页自定义
上一篇:Android GridView控件自定义中,我们自定义了Android GridView控件. 包名解释: com.yaomei.activity.adapter DEMO使用到的自定义 ...
最新文章
- Jquer学习之jQuery(function(){})与(function(){})(jQuery)之间的区别
- 最大连续子序列和-动态规划
- boost::detail模块实现boost::blank的测试程序
- zoom怎么解除静音_ZOOM视频软件使用指南(学生端)
- 单片机8×8点阵显示简单汉字的程序_LED显示屏的显示原理原来是这样,科技实现梦想...
- 5、jeecg 笔记之 minidao 条件判断
- js在类的方法中访问自己的属性
- 数据库MySQL驱动5.1.22下载_mysql-connector-java-5.1.22下载
- Mybatis破MySql8小时断线问题
- WEB前端性能优化及应用服务器性能优化和存储性能优化
- 关于xp英文版安装多国语言包的问题
- 系统功能测试用例模板
- 一道简单的CTF社工题思路
- OC5021B降压型恒流驱动控制芯片,关断时间可调
- pingpong php,php – 使用pingpong包在laravel 5.1中创建子模块文件夹
- 如何利用区块链技术保护知识产权
- java新手抖机灵(java新手技巧)
- 南方电网两栖机器人_南方电网首个作业级水下机器人落户海南 为海底电缆“护驾”...
- 康乐不风流之爱解题的pde灌水王张祖锦
- git branch分支创建、切换、合并,git tag标签