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之圆角矩形轨迹图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: realme要用天玑9000!曾把联发科
- 下一篇: 真千足!史上腿最多的虫子被发现:有130