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();
}
}
四、效果展示
RotateTrackView.gif
五、下载地址
android布局中画圆角矩形,Android 自定义View之圆角矩形轨迹图相关推荐
- android 轨迹生成图,Android自定义View实现公交成轨迹图
本文实例为大家分享了Android自定义View实现公交成轨迹图的具体代码,供大家参考,具体内容如下 总体分析下:水平方向recyclewview,item包含定位点,站台位置和站台名称. 下面看实现 ...
- 自定义View将圆角矩形绘制在Canvas上
前几天,公司一个项目中,头像图片需要添加圆角,这样UI效果会更好看,于是写了一个小的demo进行圆角的定义,该处主要是使用BitmapShader进行了渲染(如果要将一张图片裁剪成椭圆或圆形显示在屏幕 ...
- android 图片颜色渐变动画,自定义View之颜色渐变折线图
今日科技快讯 近日,汽车之家宣布与湖南卫视达成独家战略合作.据悉,双方开辟了"台网互动"营销模式,将共同开展汽车广告业务,并联合推出品效合一的新型汽车类广告产品"芒果汽车 ...
- android类中定义颜色,自定义实现简单的Android颜色选择器(附带源码)
在写Android App过程中需要一个简单的颜色选择器,Android自带的ColorPicker和网上的一些ColorPicker都太高端了,都实现了颜色渐变功能,我要的不需要那么复杂,只想提供几 ...
- Android 雪花飘落动画效果 自定义View
在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不 ...
- android 选择银行类型,『自定义View实战』—— 银行种类选择器
在工作中难免遇到自定义 View 的相关需求,本身这方面比较薄弱,因此做个记录,也是自己学习和成长的积累.自定义View实战 前言 年前的最后一个开发需求,将之前H5开卡界面转变成native.意思就 ...
- Carson带你学Android:源码解析自定义View Draw过程
前言 自定义View是Android开发者必须了解的基础 网上有大量关于自定义View原理的文章,但存在一些问题:内容不全.思路不清晰.无源码分析.简单问题复杂化 等 今天,我将全面总结自定义View ...
- Android 自定义View 圆形圆角图片
[Android 自定义View 圆形圆角图片] 基于Xfermode 实现 1.概述 在很久以前也写过一个利用Xfermode 实现圆形.圆角图片的(Android 完美实现图片圆角和圆形(对实现进 ...
- android自定义progressbar样式,Android开发中如何实现自定义ProgressBar的样式
Android开发中如何实现自定义ProgressBar的样式 发布时间:2020-11-20 16:08:10 来源:亿速云 阅读:294 作者:Leah Android开发中如何实现自定义Prog ...
最新文章
- 日记 [2008年03月23日]LINUX网关后面的pptp ***客户机连接***
- 跳水比赛背后的隐形教练现身了!百度智能云还完成了历史性的大升级
- 在Cisco交换机上实现隔离访问
- Auto packing the repository in background for optimum performance.
- STM32F7xx —— LAN8720(FreeRTOS+LWIP)
- android版 点击下载,自动点击器最新版
- SQLSERVER中的BCP命令使用
- HTTP、websocket、XMPP、COAP、MQTT和DDS协议对比
- html 编辑器插件安装,最新版CKEditor的配置方法及插件(Plugin)编写示例
- CMSIS 记录与下载
- 通过 电脑快捷键 高效利用时间
- 计算机工作的本质是什么?
- 电热毯UL964标准上架亚马逊所需资料流程
- linux yum安装svn版本号,CentOS7 yum安装svn服务
- 半年以来的图像去雾总结-图像去雾(一)暗通道去雾
- 用C++实现强化学习,速度不亚于Python,这里有个框架可用
- bootstarp怎么使盒子到最右边_8+ | 从恐龙特急克塞号到小猪佩奇,怎么都有它
- 图书信息管理系统(二)
- 第一章 略说中医的学习与研究(4)
- Android 之路18---Java基础12
热门文章
- BotSharp v0.2 发布, 支持微信智能回复
- 《你必须掌握的Entity Framework 6.x与Core 2.0》书籍出版
- AspNetCoreApi 跨域处理(CORS )
- spring cloud+dotnet core搭建微服务架构:Api网关(三)
- Windows Server Containers 支持 Windows 开发者使用 Docker
- 使用webpack搭建个性化项目
- Git 撤销操作 / 回滚历史
- mysql中的操作指令,MySQL中常用指令操作的介绍(代码示例)
- frameset在html5下用什么代替_速速围观!冬至吃货地图来啦~蚌埠的吃货们,你们今天吃什么?...
- Excel实用函数大全(名称、功能、说明、用法、举例)