日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android自定义View实践 空气质量检测 pm2.5

發(fā)布時間:2025/4/5 Android 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android自定义View实践 空气质量检测 pm2.5 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

直接先看效果圖

自定義氣體檢測視圖我們先整理下需要做的的事情

  • 畫五個圓弧
  • 每個圓弧上再通過具體的數(shù)據(jù)繪制一定角度的圓弧
  • 甲醛那個進(jìn)度條比較特殊,一頭平一頭橢圓該怎么實現(xiàn)?
  • 文字的繪制
  • 明白了需求我們開搞

    畫背景圓弧很簡單canvas.drawArc 參數(shù)分別是圓弧所在的矩形范圍、圓弧繪制的其實角度、圓弧劃過的角度,是否掃過圓心

    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) {throw new RuntimeException("Stub!");}


    好,那我們先定義加個正方形的寬度 為了適配我引用了AutoSize框架,你可以不用理會。

    float[] whiteCircle = new float[]{AutoSizeUtils.dp2px(getContext(), 192),AutoSizeUtils.dp2px(getContext(), 208),AutoSizeUtils.dp2px(getContext(), 226), AutoSizeUtils.dp2px(getContext(), 244)};

    寬度有了我們是不是要計算每個正方形放在屏幕中心是的位置也就是第一個參數(shù)RectF的構(gòu)造
    首先獲取屏幕的寬高

    @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mMeasureWidth = getMeasuredWidth();mMeasureHeight = getMeasuredHeight();}

    然后構(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)這個接口即可

    public interface GasData {String getGasName();//氣體名字int getMax();//氣體最大值int getProgress();//當(dāng)前氣體濃度int getSensorType();//氣體類型 }

    有什么不懂得聯(lián)系我 QQ910689331

    總結(jié)

    以上是生活随笔為你收集整理的Android自定义View实践 空气质量检测 pm2.5的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美乱妇视频 | 超碰av男人的天堂 | 天天干天天操天天插 | 亚洲女优一区 | 久久免费国产精品 | 国产精品国产一区 | 北条麻妃在线一区二区 | 丰满人妻熟妇乱偷人无码 | 欧美在线观看网站 | av天堂一区二区 | 少妇脚交调教玩男人的视频 | 天天综合网国产 | 日本精品久久久 | 在线免费观看黄色小视频 | 少妇精品无码一区二区免费视频 | 狠狠干在线视频 | 国产高清在线一区 | 波多野结衣一区二区三区四区 | 天天干网 | 日韩精品在线电影 | 欧美少妇一区二区三区 | 日本精品黄色 | 超碰天天干 | 播放男人添女人下边视频 | 青青草97国产精品免费观看 | 成人在线观看小视频 | 成人黄色小说在线观看 | 欧美色影院 | 91亚洲精品久久久蜜桃网站 | 一级全黄男女免费大片 | 你懂的国产在线 | 日韩国产欧美一区二区三区 | 久久久精品美女 | 日韩国产综合 | 欧美日韩中文在线 | 涩av| 欧美成人午夜视频 | 成人1区2区3区 | 免费美女视频网站 | 国产精品一二三四区 | 国产精品s | 欧美做受喷浆在线观看 | 亚洲av永久无码国产精品久久 | 婷婷丁香一区二区三区 | 黄色片视频播放 | 精品99在线观看 | 国产精品自拍合集 | 免费高清视频在线观看 | 久久久18禁一区二区三区精品 | 亚洲综合久久久 | 丁香婷婷六月天 | 永久免费成人代码 | 五月婷婷综合色 | 新香蕉视频 | 亚洲伊人精品 | 日韩三级一区 | 日本国产亚洲 | 极品粉嫩国产18尤物 | av我不卡 | 精品欧美一区二区三区免费观看 | youjizzxxx69| 亚洲另类自拍 | 国产资源久久 | 九九热视频在线观看 | 国产91黄色 | 爆操网站 | 美女搞黄在线观看 | 国产在线aaa | 精品视频在线一区二区 | 成人免费版 | 成人日韩在线观看 | 特级av| 一区二区手机在线 | av秋霞| 在线观看欧美日韩 | 亚洲欧洲一二三区 | 婷婷综合av | 一卡二卡三卡四卡 | 成人综合色站 | 成人精品视频99在线观看免费 | h片在线播放 | 国产淫片av片久久久久久 | 欧美黄色视屏 | 欧美性猛交xx乱大交 | 91精品国产一区二区三竹菊影视 | 欧美人交a欧美精品 | 国产精品色呦呦 | 成人精品福利视频 | 强伦人妻一区二区三区 | 麻豆一级片| 欧美啪啪网站 | 欧美亚洲精品一区二区 | 欧美另类高清 | 欧美一级免费在线 | 超碰伊人网 | av免费大全| 成人手机在线视频 | 精品无码人妻一区二区免费蜜桃 | 久久久久久久久一区 |