然后准备实现一波,做之前在网上找了很久,并没有相似的效果,所以自己做了一个,已经上传到我的代码库里:

欢迎小伙伴们的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立体圆柱动画效果实现_移动开发_化身孤岛的瓜...相关推荐

  1. 视频教程-Android Material Design 新控件-Android

    Android Material Design 新控件 刘志远,北京邮电大学硕士研究生, 北京育华志远科技有限公司创始人, 育华志远教育品牌负责人,育华志远课程体系打造者. 率领团队为互联网行业培训千 ...

  2. Android之——史上最简单最酷炫的3D图片浏览效果的实现

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48052709 如今,Android开发已经成为移动互联开发领域中一支不可或缺的力量 ...

  3. Android 酷炫的3d立体圆柱动画效果实现

    最近在drrible上看到一个超酷炫的效果,立体圆柱缓慢上升:https://dribbble.com/shots/7077455-Spending-analytics 然后准备实现一波,做之前在网上 ...

  4. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  5. android点击隐藏控件,Android编程实现点击EditText之外的控件隐藏软键盘功能

    本文实例讲述了Android编程实现点击EditText之外的控件隐藏软键盘功能.分享给大家供大家参考,具体如下: 工具类 ... public static void hideKeyboard(Co ...

  6. android中互斥的控件,Android控件之Radiobutton与RadioGroup

    RadioButton 是一个单选控件,在一个RadioGroup中,各个RadioButton是互斥的 XML文件: xmlns:tools="http://schemas.android ...

  7. android自定义选年控件,Android精美日历控件CalendarView自定义使用完全解析

    项目github地址 此框架采用组合的方式,各个模块互相独立,可自由采用各种提供的控件组合,完全自定义自己需要的UI,周视图和月视图可通过简单自定义任意自由绘制,不怕美工提需求!!!下面教程将介绍如何 ...

  8. android 除了webview 浏览器控件,android开发我的新浪微博客户端-OAuth认证过程中用WebView代替原来的系统自带浏览器...

    前面的文章的OAuth认证过程在获取oauth_verifier码是是通过调用android系统带的浏览器进行用户授权认证的, 具体见:android开发我的新浪微博客户端-用户授权页面功能篇(3.2 ...

  9. android bind 自动声明控件,Android注解神器ButterKnife使用说明

    阅读本文大概需要5分钟 前言 如果你还在一行一行的手写findViewById的话,只能证明你对新技术的敏感度太差,间接地暴露了你不善于接受新事物的性格特征,太过于因循守旧.按部就班,这对于一个程序员 ...

  10. android中翻页控件,Android GridView控件分页自定义

    上一篇:Android GridView控件自定义中,我们自定义了Android GridView控件. 包名解释: com.yaomei.activity.adapter   DEMO使用到的自定义 ...

最新文章

  1. Jquer学习之jQuery(function(){})与(function(){})(jQuery)之间的区别
  2. 最大连续子序列和-动态规划
  3. boost::detail模块实现boost::blank的测试程序
  4. zoom怎么解除静音_ZOOM视频软件使用指南(学生端)
  5. 单片机8×8点阵显示简单汉字的程序_LED显示屏的显示原理原来是这样,科技实现梦想...
  6. 5、jeecg 笔记之 minidao 条件判断
  7. js在类的方法中访问自己的属性
  8. 数据库MySQL驱动5.1.22下载_mysql-connector-java-5.1.22下载
  9. Mybatis破MySql8小时断线问题
  10. WEB前端性能优化及应用服务器性能优化和存储性能优化
  11. 关于xp英文版安装多国语言包的问题
  12. 系统功能测试用例模板
  13. 一道简单的CTF社工题思路
  14. OC5021B降压型恒流驱动控制芯片,关断时间可调
  15. pingpong php,php – 使用pingpong包在laravel 5.1中创建子模块文件夹
  16. 如何利用区块链技术保护知识产权
  17. java新手抖机灵(java新手技巧)
  18. 南方电网两栖机器人_南方电网首个作业级水下机器人落户海南 为海底电缆“护驾”...
  19. 康乐不风流之爱解题的pde灌水王张祖锦
  20. git branch分支创建、切换、合并,git tag标签

热门文章

  1. 计算机投诉信英语作文,英语投诉信范文
  2. Photoshop中怎么画虚线
  3. 还不认识Tux你就太low了
  4. 用Photoshop脚本批量为照片增加拍摄时间水印
  5. html引入css的三种方式
  6. 复制粘贴暴利网赚蓝海项目案例详细拆解
  7. 开放下载!《阿里巴巴Android开发手册》正式发布
  8. 从主流剪辑软件与配置标准,聊聊剪辑视频的电脑
  9. PS基础--填充颜色及命令
  10. 搭建 Hexo 个人博客和 Matery 主题的配置优化