android 扫描照片功能,Android自定义View- 雷达扫描图
首先來看看效果圖:CSDN博客地址
這里寫圖片描述
這里我使用了兩種實現方式:
繼承 view 實現。
繼承 surfaceview 實現。
為什么會有兩種實現方式呢?
主要是因為我在繼續加入一些自定義功能的時候,如果是繼承 view ,出現了卡頓的現象,也就是說在 UI 線程中做的邏輯操作太多了,導致 UI 線程失幀,最終導致了卡頓現象。又考慮到有些童鞋還沒有學習 surfaceview ,所以會用兩種方式去實現。文章末尾會貼出 GitHub 地址,所以這里只會貼出核心內容。
先簡要說一下這里需要涉及到的知識點:
surfaceview
ValueAnimator (可選)
高中三角函數 Math.sin() Math.cos()。
繪制思路
繪制一個圓,顏色圍繞圓心漸變。
讓這個圓圍繞圓心不斷旋轉,就有了掃描的效果。
根據半徑生成隨機的紅點,當數量超過 5 個的時候,去掉最后一個點,讓數量一直保持5個。
第一步:繪制一個漸變圓
ok,先看效果圖:
這里寫圖片描述
初始化成員變量:
private int radius;//圓半徑
private String TAG = "zoneLog";//Log 日志的 tag
private Matrix matrix;//view 的矩陣參數,用于旋轉圓形
private float sweepAngle;//
private boolean isStart;//是否開始 valueanimator
private int value1;//valueanimator 的漸變值
private int x;//紅點的 x 坐標值
private int y;//紅點的 y 坐標值
private int totalAngle;//總旋轉角度
private Paint redPointPaint;//紅點畫筆
private Paint sweepPaint;//圓形畫筆,繪制圓角漸變
private Paint strokeWhitePaint;//描邊白色畫筆,用于繪制空心圓圈
private List pointList;//記錄紅點的坐標
private void init() {
matrix = new Matrix();
post(runnable);//用于實現圓形的不斷旋轉
handler.sendEmptyMessageDelayed(0, 1000);
isStart = true;
pointList = new ArrayList<>();
radius = 300;
sweepAngle = 8;//旋轉角度
redPointPaint = new Paint();
redPointPaint.setAntiAlias(true);
redPointPaint.setColor(Color.RED);
redPointPaint.setStyle(Paint.Style.FILL_AND_STROKE);
sweepPaint = new Paint();
sweepPaint.setAntiAlias(true);
sweepPaint.setStyle(Paint.Style.FILL_AND_STROKE);
SweepGradient sweepGradient = new SweepGradient(0, 0, new int[]{0X10000000, Color.WHITE}, null);//角度漸變,由透明變為白色
sweepPaint.setShader(sweepGradient);//設置 shader
strokeWhitePaint = new Paint();
strokeWhitePaint.setAntiAlias(true);
strokeWhitePaint.setColor(Color.WHITE);
strokeWhitePaint.setStyle(Paint.Style.STROKE);
strokeWhitePaint.setStrokeWidth(1);
}
用于記錄小紅點:
class MyPoint {//用于記錄小紅點的圓心
int x;
int y;
float angle;
public MyPoint(int x, int y, float angle) {
this.x = x;
this.y = y;
this.angle = angle;
}
}
初始化完成后即可進行相關的繪制工作了:
canvas.drawColor(getResources().getColor(R.color.huaweiClockView));//繪制背景顏色
canvas.save();//在另外一個圖層來繪制圓形,否則會影響到后續操作
canvas.concat(matrix);//獲取 view 的矩陣參數
canvas.translate(getWidth() / 2, getHeight() / 2);//將原點移動至中心
canvas.drawCircle(0, 0, radius, sweepPaint);//繪制漸變圓
canvas.drawCircle(0, 0, radius + 80, strokeWhitePaint);//以下是繪制描邊圓圈
canvas.drawCircle(0, 0, radius - 80, strokeWhitePaint);//
canvas.drawCircle(0, 0, radius - 160, strokeWhitePaint);//
canvas.drawCircle(0, 0, radius - 240, strokeWhitePaint);//
canvas.restore();//合并之前的操作,相當于 photoshop 中的圖層合并
第二步:讓圓轉動起來
這里通過修改 view 的矩陣參數,讓其實現旋轉,我們肉眼看起來,也就實現了掃描的效果。先看效果:
這里寫圖片描述
private Runnable runnable = new Runnable() {
@Override
public void run() {
totalAngle += sweepAngle;//統計總的旋轉角度
matrix.postRotate(sweepAngle, getWidth() / 2, getHeight() / 2);//旋轉矩陣,旋轉 8 度。
postInvalidate();//刷新
postDelayed(runnable, 200);//調用自身,實現不斷循環
}
};
第三步:生成小紅點
這里通過 handler 來不斷生成小紅點,而且讓小紅點有一定的停留時間。且跟隨掃描的腳步去生成。
來看 一下效果圖:
這里寫圖片描述
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
int currentAngle = totalAngle % 360;//計算出一個圓范圍內的旋轉角度
int currentRadius = (int) (radius * Math.random()) + 50;//隨機取得一個半徑
x = (int) (currentRadius * Math.cos(currentAngle));//通過三角函數,計算出 x y 坐標值
y = (int) (currentRadius * Math.sin(currentAngle));
if (currentAngle > 0 && currentAngle < 90) {//計算出各個象限的情況
x = Math.abs(x);
y = Math.abs(y);
} else if (currentAngle > 90 && currentAngle < 180) {
x = -Math.abs(x);
y = Math.abs(y);
} else if (currentAngle > 180 && currentAngle < 270) {
x = -Math.abs(x);
y = -Math.abs(y);
} else if (currentAngle > 270 && currentAngle < 360) {
y = -Math.abs(y);
x = Math.abs(x);
} else if (currentAngle == 0 || currentAngle == 360) {
y = 0;
x = Math.abs(x);
} else if (currentAngle == 90) {
x = 0;
y = Math.abs(y);
} else if (currentAngle == 180) {
y = 0;
x = -Math.abs(x);
} else if (currentAngle == 270) {
x = 0;
y = -Math.abs(y);
}
pointList.add(0, new MyPoint(x, y, totalAngle));
if (pointList.size() > 5) {//超過 5 個數據時,抹掉最后一個數據
pointList.remove(pointList.size() - 1);
}
handler.sendEmptyMessageDelayed(0, 1000);//發送 message 實現不斷循環
}
}
};
在 ondraw() 中追加以下代碼,繪制小紅點:
canvas.translate(getWidth() / 2, getHeight() / 2);
for (int i = 0; i < pointList.size(); i++) {
canvas.drawCircle(pointList.get(i).x, pointList.get(i).y, 30, redPointPaint);
}
canvas.restore();
好的,我們一步一步完成了雷達掃描圖的繪制,路下來可能還有點懵逼,那么就看看整一段的代碼吧。
view實現
surfaceview實現
如果文中有什么知識點是錯誤的或者更好的實現方法,請及時聯系我進行修改,以免誤導別人。謝謝。
最后還有一種效果是這樣的,這里就不過多講解了,可以進源碼看看,哈哈。
這里寫圖片描述
總結
以上是生活随笔為你收集整理的android 扫描照片功能,Android自定义View- 雷达扫描图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DDoS攻击的检测和防御在计算机网络安全
- 下一篇: android colorstateli