android布局中画圆角矩形,Android 自定义View之圆角矩形轨迹图

一、原理说明

主要是通过计算轨迹的坐标点加入到集合中,然后对集合进行相应截取,传入canvas中。

二、具体代码实现

/**

* 原理是先通过尺寸把各个轨迹的坐标计算出来,然后再截取相应坐标,进行重绘。

*

* @author lz

* @Time 2019-3-27

*/

public class RotateTrackView extends View {

/**

* 起始点横坐标

*/

private float startXPoint;

/**

* 起始点纵坐标

*/

private float startYPoint;

/**

* 宽度

*/

private float width;

/**

* 高度

*/

private float heigth;

/**

* 圆角半径

*/

private float radius;

/**

* 图形点集合

*/

float[] mPoints;

/**

* 画笔

*/

private Paint mPaint;

/**

* 标志位

*/

private final int LeftUp = 0;

private final int LeftDown = 1;

private final int RightDown = 2;

private final int RightUp = 3;

/**

* 停止动画标志位

*/

private boolean isPause = false;

/**

* 动画开始位置起点

*/

private int indexBegin = 0;

/**

* 动画结束位置,也就是整个动画的长度

*/

private int indexEnd = 200;

private int LENGTH = 200;

private int TIME = 1;

/**

* 截取的轨迹点集合

*/

private float[] snackPoints;

public RotateTrackView(Context context) {

super(context);

}

public RotateTrackView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public RotateTrackView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

public RotateTrackView(Context context, float startXPoint, float startYPoint, float width, float heigth, float radius) {

this(context);

this.startXPoint = startXPoint;

this.startYPoint = startYPoint;

this.heigth = heigth;

this.width = width;

this.radius = radius;

// 初始化画笔

mPaint = new Paint();

mPaint.setColor(Color.RED);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setStrokeWidth(8);

// 轨迹计算

ArrayList mPointLists = new ArrayList<>();

addXPoints(width, radius, startXPoint, startYPoint, mPointLists);

addCircleArgle(RightUp, radius, mPointLists);

addYPoints(heigth, radius, mPointLists.get(mPointLists.size() - 1), mPointLists.get(mPointLists.size() - 2), mPointLists);

addCircleArgle(RightDown, radius, mPointLists);

reduceXPoints(width, radius, mPointLists.get(mPointLists.size() - 2), mPointLists.get(mPointLists.size() - 1), mPointLists);

addCircleArgle(LeftDown, radius, mPointLists);

reduceYPoints(heigth, radius, mPointLists.get(mPointLists.size() - 1), mPointLists.get(mPointLists.size() - 2), mPointLists);

addCircleArgle(LeftUp, radius, mPointLists);

// 将list集合转换成canvas接受的float数组

mPoints = new float[mPointLists.size()];

for (int i = 0; i < mPointLists.size(); i++) {

mPoints[i] = mPointLists.get(i);

}

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (snackPoints.length == LENGTH) {

canvas.drawPoints(snackPoints, mPaint);

}

}

/**

* x轴向右计算

*

* @param length

* @param radius

* @param addNumber

* @param constantNumber

* @param list

*/

private void addXPoints(float length, float radius, float addNumber, float constantNumber, List list) {

for (int i = 1; i < (length - 2 * radius); i++) {

float pointX = addNumber + i;

float pointY = constantNumber;

list.add(pointX);

list.add(pointY);

}

}

private void reduceXPoints(float length, float radius, float addNumber, float constantNumber, List list) {

for (int i = 1; i < (length - 2 * radius); i++) {

float pointX = addNumber - i;

float pointY = constantNumber;

list.add(pointX);

list.add(pointY);

}

}

private void addYPoints(float length, float radius, float addNumber, float constantNumber, List list) {

for (int i = 1; i < (length - 2 * radius); i++) {

float pointX = addNumber + i;

float pointY = constantNumber;

list.add(pointY);

list.add(pointX);

}

}

private void reduceYPoints(float length, float radius, float addNumber, float constantNumber, List list) {

for (int i = 1; i < (length - 2 * radius); i++) {

float pointX = addNumber - i;

float pointY = constantNumber;

list.add(pointY);

list.add(pointX);

}

}

/**

* 由于上下左右四个圆的轨迹坐标计算方式是不一样的,需要单独处理

*

* @param position

* @param radius

* @param list

*/

private void addCircleArgle(int position, float radius, List list) {

int argle = 0;

float x = list.get(list.size() - 2);

float y = list.get(list.size() - 1);

for (int i = 0; i < 90; i += 10) {

argle = i + 10;

switch (position) {

case RightUp:

float x1 = (float) (x + Math.sin((Math.PI / 180) * argle) * radius);

float y1 = (float) (y + (radius - Math.cos((Math.PI / 180) * argle) * radius));

list.add(x1);

list.add(y1);

break;

case RightDown:

float x2 = (float) (x - (radius - Math.cos((Math.PI / 180) * argle) * radius));

float y2 = (float) (y + (Math.sin((Math.PI / 180) * argle) * radius));

list.add(x2);

list.add(y2);

break;

case LeftDown:

float x3 = (float) (x - (Math.sin((Math.PI / 180) * argle) * radius));

float y3 = (float) (y - (radius - Math.cos((Math.PI / 180) * argle) * radius));

list.add(x3);

list.add(y3);

break;

case LeftUp:

float x4 = (float) (x + (radius - Math.cos((Math.PI / 180) * argle) * radius));

float y4 = (float) (y - (Math.sin((Math.PI / 180) * argle) * radius));

list.add((float) (x + (radius - Math.cos((Math.PI / 180) * argle) * radius)));

list.add((float) (y - (Math.sin((Math.PI / 180) * argle) * radius)));

break;

default:

break;

}

}

}

/**

* 开始动画

*/

public void startAnim() {

Thread thread = new Thread() {

@Override

public void run() {

super.run();

while (!isPause) {

RotateTrackView.this.post(new Runnable() {

@Override

public void run() {

invalidate();

}

});

indexBegin += 2;

indexEnd += 2;

if (indexEnd < mPoints.length) {

snackPoints = (Arrays.copyOfRange(mPoints, indexBegin, indexEnd));

} else if (indexBegin == mPoints.length) {

indexBegin = 0;

indexEnd = LENGTH;

} else {

float[] floats2 = Arrays.copyOfRange(mPoints, indexBegin, mPoints.length);

float[] floats3 = Arrays.copyOf(floats2, LENGTH);

int length = floats2.length;

for (int i = 0; i < (LENGTH - floats2.length); i++) {

floats3[length] = mPoints[i];

length++;

}

snackPoints = floats3;

}

try {

Thread.sleep(TIME);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

};

thread.start();

}

/**

* 停止动画

*/

public void stopAnim() {

isPause = true;

}

/**

* 设置轨迹粗细

*/

public void setLinesWidth(int width) {

mPaint.setStrokeWidth(width);

}

}

三、使用方法

public class MainActivity extends AppCompatActivity {

private RotateTrackView rotateTrackView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// 创建RotateTrackView, 设置起始坐标、宽、高、圆角半径

rotateTrackView = new RotateTrackView(this, 500, 600, 250, 180, 30);

setContentView(rotateTrackView);

// 设置画笔粗细

rotateTrackView.setLinesWidth(20);

// 开始动画

rotateTrackView.startAnim();

}

}

四、效果展示

69ff3cf89e07

RotateTrackView.gif

五、下载地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300851.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

类QQ右下角弹出框(Qt)

2019独角兽企业重金招聘Python工程师标准>>> 使用Qt写的类QQ右下角弹出框 /***main.cpp */ #include <QtGui/QApplication> #include "dialog.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);Dialog w;w.show();return a.exec()…

实现贝叶斯分类器_机器学习实战项目-朴素贝叶斯

朴素贝叶斯 概述贝叶斯分类是一类分类算法的总称&#xff0c;这类算法均以贝叶斯定理为基础&#xff0c;故统称为贝叶斯分类。本章首先介绍贝叶斯分类算法的基础——贝叶斯定理。最后&#xff0c;我们通过实例来讨论贝叶斯分类的中最简单的一种: 朴素贝叶斯分类。贝叶斯理论 &a…

设计模式(1)

一、 C# 面向对象程序设计复习 点击http://files.cnblogs.com/zhenyulu/CSharp.rar下载&#xff0c;内容包括&#xff1a; 字段与属性.cs 属性、方法作用范围.cs 一加到一百.cs 使用接口排序(2).cs 使用接口排序(1).cs 求质数.cs 冒泡法排序.cs 九九表.cs 静态与非静态…

UILabel自适应高度和自动换行

码&#xff1a; [plain] view plaincopy //初始化label UILabel *label [[UILabel alloc] initWithFrame:CGRectMake(0,0,0,0)]; //设置自动行数与字符换行 [label setNumberOfLines:0]; label.lineBreakMode UILineBreakModeWordWrap; // 测试字串 NSString *s &qu…

你怎么了珍妮,你醒醒啊珍妮~ | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源网络&#xff0c;侵权删&#xff09;太惨了我知道我不应该笑我得点完“再看”再笑↓ ↓ ↓

鸿蒙蕴含的哲理,经典别致的人生语录,蕴含哲理,受用一生!

一、人生永远是这个道理&#xff1a;在意的越多&#xff0c;遇到的麻烦就会越多什么都不在乎的人&#xff0c;反倒一点麻烦都没有——苏芩二、生活总是这样&#xff0c;不能叫人处处都满意&#xff0c;但我们还要热情地活下去。——路遥三、要想幸福一点&#xff0c;心就要简单…

微软面向初学者的机器学习课程:1.3-机器学习中的公平性

写在前面&#xff1a;最近在参与microsoft/ML-For-Beginners的翻译活动&#xff0c;欢迎有兴趣的朋友加入&#xff08;https://github.com/microsoft/ML-For-Beginners/issues/71&#xff09;机器学习中的公平性作者Tomomi Imura课前测验介绍在本课程中&#xff0c;您将开始了解…

python +appium实现原理_python_appium使用原理

一。appium介绍Appium是一个开源测试自动化框架&#xff0c;可用于原生&#xff0c;混合和移动Web应用程序测试。 它使用WebDriver协议驱动iOS&#xff0c;Android和Windows应用程序。多平台支持&#xff1a;三种APP&#xff1a;-原生APP类型 --原生应用-web app类型 --移动应…

[每日一题] 11gOCP 1z0-052 :2013-09-23 Oracle11g 内存参数设置...................................C7...

转载请注明出处&#xff1a;http://blog.csdn.net/guoyjoe/article/details/11924597正确答案&#xff1a;CD&#xff08;题库给出的答案是AD&#xff0c;大家要相信自己&#xff0c;有些答案是错的&#xff01;一切以实战为依据&#xff09;一、我们先来看Oracle 11g内存架构图…

童年各大名场面~ | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源网络&#xff0c;侵权删&#xff09;随便一截就是表情包↓ ↓ ↓

android mvvm流程图,MVVM框架模式详解

MVVM 定义MVVM 是 Model-View-ViewModel 的缩写&#xff0c;它是一种基于前端开发的架构模式&#xff0c;其核心是提供对 View 和 ViewModel 的双向数据绑定&#xff0c;这使得 ViewModel 的状态改变可以自动传递给 View&#xff0c;即所谓的数据双向绑定。在 MVVM 的框架下视图…

算是长大了

20年前的今天我出生了转载于:https://www.cnblogs.com/melorain/archive/2006/10/31/546197.html

Windows 11 操作系统最低硬件要求

以下是在您电脑上安装 Windows 11 操作系统的最低要求。如果您的电脑不满足这些要求&#xff0c;您可能无法在设备上安装全新的 Windows 11 操作系统。处理器&#xff08; CPU&#xff09;&#xff1a;1 GHz 或更快的支持 64 位的中央处理器&#xff08;双核或多核&#xff09;…

ppt扇形图怎么显示数据_前方高能!多维数据分析的神器雷达图PPT制作教程来啦!...

数据的可视化呈现&#xff0c;是最近几年的一个热门词&#xff0c;尤其是在各种PPT的制作中&#xff0c;观看者越来越希望通过简单直接的方式了解到数据背后的深刻含义&#xff0c;因此&#xff0c;之前我们也专门为大家分享了为什么要在PPT里去做数据的可视化呈现&#xff0c;…

html5 canvas 像素 碰撞检测,碰撞检测 · HTML5 Canvas半知半解 · 看云

## 碰撞检测碰撞检测是物体与物体之间的交互&#xff0c;其实在前面的边界检测也是一种碰撞检测&#xff0c;只不过检测的对象是物体与边界之间。在本章中&#xff0c;我们将介绍更多的碰撞检测&#xff0c;比如&#xff1a;两个物体间的碰撞检测、一个物体与一个点的碰撞检测、…

法国一家夜总会上演机器人钢管舞

全世界只有3.14 % 的人关注了青少年数学之旅星空新闻报道&#xff0c;法国SC-Club夜总会9月3日邀请机器人跳钢管舞&#xff0c;庆祝其开业5周年。该机器人脚踩高跟鞋&#xff0c;头上是一台CCTV监控仪。发明者称&#xff0c;这是为了引发人们对于“窥探”的思考。店主表示这次演…

AJAX,只是一种过渡技术吗?

在CSDN首页上用大标题写着“谁来革AJAX的命&#xff0c;Flash还是WPF”&#xff0c;同时在下面列举了Adobe推出Flex 2.0 力拼Ajax&#xff0c;以及袁红岗在6月份的文章Ajax&#xff0c;只是一种过渡技术&#xff0c;其中袁在文章中说到“Ajax其实是一种新瓶装旧酒的过渡技术&am…

li或dd 浮动后增加图片时高度多出3-5px的问题

转载的&#xff0c;确实能解决问题&#xff0c;原因不明&#xff0c;求指教&#xff0c;谢谢&#xff01; 本人实验&#xff0c;chrome下多出3px&#xff0c;firefox下多出5px li或dd 浮动后增加图片时高度多出3-5px的问题 dd或li或a标签内&#xff0c;插入图片后&#xff0c;下…

Binding(三):资源和ValueConverter

这节讲资源和值转换器(ValueConverter)。资源在XAML中&#xff0c;我们想要使用外部的数据或者类&#xff0c;需要引入其命名空间&#xff0c;然后将其定义为XAML页面的资源&#xff0c;供给控件使用&#xff0c;或者我们需要封装一个共用的样式&#xff0c;同样也需要定义成资…

c语言 overflow_C语言和其他语言的不得不说的差别!

提到C语言&#xff0c;我们知道c语言和其他高级语言的最大的区别就是C语言是要操作内存的&#xff01;我们需要知道——变量&#xff0c;其实是内存地址的一个抽像名字罢了。在静态编译的程序中&#xff0c;所有的变量名都会在编译时被转成内存地址。机器是不知道我们取的名字的…