Android自定义View实践 空气质量检测 pm2.5
生活随笔
收集整理的這篇文章主要介紹了
Android自定义View实践 空气质量检测 pm2.5
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
直接先看效果圖
自定義氣體檢測視圖我們先整理下需要做的的事情
明白了需求我們開搞
畫背景圓弧很簡單canvas.drawArc 參數(shù)分別是圓弧所在的矩形范圍、圓弧繪制的其實角度、圓弧劃過的角度,是否掃過圓心
public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) {throw new RuntimeException("Stub!");}
好,那我們先定義加個正方形的寬度 為了適配我引用了AutoSize框架,你可以不用理會。
寬度有了我們是不是要計算每個正方形放在屏幕中心是的位置也就是第一個參數(shù)RectF的構(gòu)造
首先獲取屏幕的寬高
然后構(gòu)造這個RectF
public RectF(float left, float top, float right, float bottom) {throw new RuntimeException("Stub!");}
看懂了吧 上下左右分別對應(yīng)的長度如圖所示,再看不懂就自己消化下!
那么得出
float left = mMeasureWidth / 2 - 正方形寬 / 2 float top = mMeasureHeight / 2 - 正方形寬 / 2 float right = mMeasureWidth / 2 + 正方形寬 / 2 float left = mMeasureHeight / 2 + 正方形寬 / 2RectF rect = new RectF(mMeasureWidth / 2 - progressR / 2,mMeasureHeight / 2 - progressR / 2,mMeasureWidth / 2 + progressR / 2,mMeasureHeight / 2 + progressR / 2);第一個參數(shù)搞定,起始角度90度 劃過的角度270。不劃過圓心。畫筆
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);paint.setStyle(Paint.Style.STROKE);/描邊模式paint.setColor(Color.parseColor("#958280"));//灰色圓弧paint.setStrokeWidth(grayPaintWidth);//圓弧寬度paint.setStrokeCap(Paint.Cap.BUTT);//兩頭方形canvas.drawArc(rect, 90, 270, false, paint);//最終繪制好一個圓弧那么接下來開始繪制進(jìn)度條,除了甲醛的其他都好辦,改變畫筆顏色按角度繪制就行了
//繪制白色圓paint.setColor(Color.WHITE);paint.setStrokeWidth(whitePaintWidth);float arc = 270 * gasData.getProgress() / gasData.getMax();if(arc>270) arc = 270;paint.setColor(Color.WHITE);paint.setStrokeWidth(4);canvas.drawArc(rect, 90, arc, false, paint);甲醛這個該咋整?
畫筆有個屬性可以設(shè)置橢圓或者方形,但是貌似沒有一邊圓弧一邊方形的,那就來個投機(jī)取巧。先畫一個方形的小塊再接上圓角的。類似這樣你懂的吧。
還有個綠點的繪制。這里我們要用到一個公式,已知圓心、半徑、角度求圓上點的坐標(biāo)
float radius = pmProgressWidth / 2;float x = (float) (centerX + Math.cos(radian) * radius);float y = (float) (centerY + Math.sin(radian) * radius); //arc角度大于3我們畫 如果小于3直接畫個綠點即可 if (arc >= 3) {paint.setStrokeCap(Paint.Cap.SQUARE);canvas.drawArc(rect, 93, 1, false, paint);paint.setStrokeCap(Paint.Cap.ROUND);canvas.drawArc(rect, 94, arc, false, paint);float radian = (float) Math.toRadians(arc + 93);float centerX = rect.centerX();float centerY = rect.centerY();float radius = pmProgressWidth / 2;float x = (float) (centerX + Math.cos(radian) * radius);float y = (float) (centerY + Math.sin(radian) * radius);paint.setColor(Color.RED);RectF rectDot = new RectF(x - pmPaintWidth / 2, y - pmPaintWidth / 2, x + pmPaintWidth / 2, y + pmPaintWidth / 2);//繪制甲醛圖片背景canvas.drawBitmap(dotImg, null, rectDot, null);} else {//繪制甲醛圖片背景canvas.drawBitmap(dotImg, rect.centerX() - pmPaintWidth / 2, rect.bottom - pmPaintWidth / 2, null);}接下來畫文字
這里借助Path這類,在路徑上畫文字
//繪制甲醛文字Path path = new Path();path.moveTo(mMeasureWidth / 2 + 15, rect.bottom + 10);//移動到圓形下方path.lineTo(mMeasureWidth, rect.bottom);//水平的路徑textPaint.setTextSize(AutoSizeUtils.dp2px(getContext(), 14));canvas.drawTextOnPath(gasData.getGasName(), path, 0, 0, textPaint);//畫文字大功告成,最后貼上完整代碼。你等的不就是這么。。
GasView.java
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View;import com.iisfree.smarthome.R; import com.iisfree.smarthome.model.bean.DeviceBean;import java.util.ArrayList; import java.util.List;import me.jessyan.autosize.utils.AutoSizeUtils;public class GasView extends View {private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);private Paint textPaint;private List<GasData> gasDataList;private int mMeasureHeight;private int mMeasureWidth;private float whitePaintWidth;//白色圓弧寬度private float grayPaintWidth;//灰色圓弧寬度private float pmPaintWidth;//紅色圓點寬度private float bgWidth;//背景圖大小private float bgProgressWidth;//進(jìn)度圖大小private Bitmap imgBg;private Bitmap imgProgressBg;private Bitmap dotImg;private float[] whiteCircle;private float pmProgressWidth;//彩色進(jìn)度條的半徑public GasView(Context context) {super(context);initPaint(context);}public GasView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);initPaint(context);}public GasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initPaint(context);}private void initPaint(Context context) {gasDataList = new ArrayList<>();paint.setStyle(Paint.Style.STROKE);paint.setColor(Color.WHITE);textPaint = new Paint();textPaint.setAntiAlias(true);textPaint.setTextSize(AutoSizeUtils.dp2px(getContext(), 8));textPaint.setColor(Color.parseColor("#666666"));textPaint.setStyle(Paint.Style.FILL);whitePaintWidth = AutoSizeUtils.dp2px(getContext(), 2);//白色圓弧寬度grayPaintWidth = AutoSizeUtils.dp2px(getContext(), 1);//灰色圓弧寬度pmPaintWidth = AutoSizeUtils.dp2px(getContext(), 13);//紅色圓點寬度bgWidth = AutoSizeUtils.dp2px(getContext(), 136);//紅色圓點寬度bgProgressWidth = AutoSizeUtils.dp2px(getContext(), 168);//紅色圓點寬度pmProgressWidth = AutoSizeUtils.dp2px(getContext(), 157);whiteCircle = new float[]{AutoSizeUtils.dp2px(getContext(), 192),AutoSizeUtils.dp2px(getContext(), 208),AutoSizeUtils.dp2px(getContext(), 226), AutoSizeUtils.dp2px(getContext(), 244)};//繪制背景圖片BitmapFactory.Options option = new BitmapFactory.Options();option.inScaled = false;option.inPreferredConfig = Bitmap.Config.ARGB_8888;imgBg = BitmapFactory.decodeResource(getResources(), R.mipmap.air_img_03, option).copy(Bitmap.Config.ARGB_8888, true);imgProgressBg = BitmapFactory.decodeResource(getResources(), R.mipmap.air_img_02, option).copy(Bitmap.Config.ARGB_8888, true);dotImg = BitmapFactory.decodeResource(getResources(), R.mipmap.air_img_01, option).copy(Bitmap.Config.ARGB_8888, true);}public void freshData(List<DeviceBean.SrDevice.SubAirSensor> gasDataList) {this.gasDataList.clear();this.gasDataList.addAll(gasDataList);postInvalidate();}private static final String TAG = "GasView";@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (this.gasDataList == null || this.gasDataList.size() == 0) return;paint.setStrokeCap(Paint.Cap.BUTT);RectF rectF = new RectF(mMeasureWidth / 2 - bgWidth / 2,mMeasureHeight / 2 - bgWidth / 2,mMeasureWidth / 2 + bgWidth / 2,mMeasureHeight / 2 + bgWidth / 2);//繪制背景圖片canvas.drawBitmap(imgBg, null, rectF, null);RectF recBg = new RectF(mMeasureWidth / 2 - bgProgressWidth / 2,mMeasureHeight / 2 - bgProgressWidth / 2,mMeasureWidth / 2 + bgProgressWidth / 2,mMeasureHeight / 2 + bgProgressWidth / 2);//繪制甲醛圖片背景canvas.drawBitmap(imgProgressBg, null, recBg, null);for (GasData gasData : gasDataList) {float progressR = 0;switch (gasData.getSensorType()) {case 0: {drawCh2o(canvas, gasData);}break;case 1: {progressR = whiteCircle[0];}break;case 2: {progressR = whiteCircle[1];}break;case 3: {progressR = whiteCircle[2];}break;case 4: {progressR = whiteCircle[3];}break;}if (gasData.getSensorType() != 0) {RectF rect = new RectF(mMeasureWidth / 2 - progressR / 2,mMeasureHeight / 2 - progressR / 2,mMeasureWidth / 2 + progressR / 2,mMeasureHeight / 2 + progressR / 2);//繪制灰色圓paint.setColor(Color.parseColor("#958280"));paint.setStrokeWidth(grayPaintWidth);canvas.drawArc(rect, 90, 270, false, paint);//繪制白色圓paint.setColor(Color.WHITE);paint.setStrokeWidth(whitePaintWidth);float arc = 270 * gasData.getProgress() / gasData.getMax();if(arc>270) arc = 270;paint.setColor(Color.WHITE);paint.setStrokeWidth(4);canvas.drawArc(rect, 90, arc, false, paint);Path path = new Path();path.moveTo(mMeasureWidth / 2 + 20, rect.bottom + 5);path.lineTo(mMeasureWidth, rect.bottom);textPaint.setTextSize(AutoSizeUtils.dp2px(getContext(), 8));canvas.drawTextOnPath(gasData.getGasName(), path, 0, 0, textPaint);}}}private void drawCh2o(Canvas canvas, GasData gasData) {//繪制甲醛float arc = 270 * gasData.getProgress() / gasData.getMax();if(arc>270) arc = 270;paint.setColor(Color.WHITE);paint.setStrokeWidth(pmPaintWidth);RectF rect = new RectF(mMeasureWidth / 2 - pmProgressWidth / 2,mMeasureHeight / 2 - pmProgressWidth / 2,mMeasureWidth / 2 + pmProgressWidth / 2,mMeasureHeight / 2 + pmProgressWidth / 2);Log.d(TAG, "onDraw角度: " + arc);if (arc >= 3) {paint.setStrokeCap(Paint.Cap.SQUARE);canvas.drawArc(rect, 93, 1, false, paint);paint.setStrokeCap(Paint.Cap.ROUND);canvas.drawArc(rect, 94, arc, false, paint);float radian = (float) Math.toRadians(arc + 93);float centerX = rect.centerX();float centerY = rect.centerY();float radius = pmProgressWidth / 2;float x = (float) (centerX + Math.cos(radian) * radius);float y = (float) (centerY + Math.sin(radian) * radius);paint.setColor(Color.RED);RectF rectDot = new RectF(x - pmPaintWidth / 2, y - pmPaintWidth / 2, x + pmPaintWidth / 2, y + pmPaintWidth / 2);//繪制甲醛圖片背景canvas.drawBitmap(dotImg, null, rectDot, null);} else {//繪制甲醛圖片背景canvas.drawBitmap(dotImg, rect.centerX() - pmPaintWidth / 2, rect.bottom - pmPaintWidth / 2, null);}//繪制甲醛文字Path path = new Path();path.moveTo(mMeasureWidth / 2 + 15, rect.bottom + 10);path.lineTo(mMeasureWidth, rect.bottom);textPaint.setTextSize(AutoSizeUtils.dp2px(getContext(), 14));canvas.drawTextOnPath(gasData.getGasName(), path, 0, 0, textPaint);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mMeasureWidth = getMeasuredWidth();mMeasureHeight = getMeasuredHeight();} }GasData.java
自己的數(shù)據(jù)實體實現(xiàn)這個接口即可
有什么不懂得聯(lián)系我 QQ910689331
總結(jié)
以上是生活随笔為你收集整理的Android自定义View实践 空气质量检测 pm2.5的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu16.04 搭建Jenkin
- 下一篇: Android CameraSurfac