日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Android自定義View實現圓弧進度的效果

瀏覽:84日期:2022-09-21 08:07:04

前言

Android開發中,常常自定義View實現自己想要的效果,當然自定義View也是Android開發中比較難的部分,涉及到的知識有Canvas(畫布),Paint(畫筆)等,自定義控件分為三種:一是直接繼承自View,完全的自定義;二是在原有控件的基礎上進行改造,達到自己想要的效果;還有一種就是自定義組合控件,將已有的控件根據自己的需要進行組合實現的效果。本人對自定義View也是一知半解,簡單記錄下自己學習自定義View(繼承自View)的過程,方便日后翻閱。

使用技術

1、繼承View2、Canvas3、paint

效果圖:

Android自定義View實現圓弧進度的效果

1.分析組件

自定義view首先我們要分析組件是由幾部分組成,然后在依次順序使用canvas畫出組件,首先可以看出該組件由一個背景外部圓,一個圓弧,以及圓弧端點是由兩個圓組成,內部是三個文字。分析完畢,我們就可以先定義組件屬性了

2.組件屬性

1.在values目錄下新建attrs.xml文件,用來編寫組件屬性

<?xml version='1.0' encoding='utf-8'?><resources> <declare-styleable name='ProgressView'> <attr name='title' format='string'/> <attr name='num' format='string'/> <attr name='unit' format='string'/> <attr name='titleTextsize' format='dimension'/> <attr name='numTextsize' format='dimension'/> <attr name='unitTextsize' format='dimension'/> <attr name='titleTextColor' format='color'/> <attr name='numTextColor' format='color'/> <attr name='unitTextColor' format='color'/> <attr name='backCircleWidth' format='dimension'/> <attr name='outerCircleWidth' format='dimension'/> <attr name='backCircleColor' format='color'/> <attr name='outerCircleColor' format='color'/> <attr name='endCircleWidth' format='dimension'/> <attr name='edgeDistance' format='dimension'/> <attr name='endCircleColor' format='color'/> <attr name='currentPercent' format='float'/> </declare-styleable></resources>

2.自定義view繼承View并實現構造方法

public class ProgressView extends View {/** * 在java代碼里new的時候會用到 * @param context */ public ProgressView(Context context) { super(context); init(context, null); } /** * 在xml布局文件中使用時自動調用 * @param context */ public ProgressView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context,attrs); } /** * 不會自動調用,如果有默認style時,在第二個構造函數中調用 * @param context * @param attrs * @param defStyleAttr */ public ProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }}

2.初始化屬性

/** * 初始化屬性 * @param context * @param attrs */ private void init(Context context,AttributeSet attrs){ this.mContext = context; if(attrs!=null){ TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressView); title = array.getString(R.styleable.ProgressView_title); num = array.getString(R.styleable.ProgressView_num); unit = array.getString(R.styleable.ProgressView_unit); titleTextsize = array.getDimension(R.styleable.ProgressView_titleTextsize,24); numTextsize = array.getDimension(R.styleable.ProgressView_numTextsize,48); unitTextsize = array.getDimension(R.styleable.ProgressView_unitTextsize,24); titleTextColor = array.getColor(R.styleable.ProgressView_titleTextColor, Color.parseColor('#656d78')); numTextColor = array.getColor(R.styleable.ProgressView_numTextColor, Color.parseColor('#4fc1e9')); unitTextColor = array.getColor(R.styleable.ProgressView_unitTextColor, Color.parseColor('#4fc1e9')); backCircleWidth = array.getDimension(R.styleable.ProgressView_backCircleWidth, 12); outerCircleWidth = array.getDimension(R.styleable.ProgressView_outerCircleWidth, 20); backCircleColor = array.getColor(R.styleable.ProgressView_backCircleColor, Color.parseColor('#e6e9ed')); outerCircleColor = array.getColor(R.styleable.ProgressView_outerCircleColor, Color.parseColor('#4fc1e9')); endCircleWidth = array.getDimension(R.styleable.ProgressView_endCircleWidth,24); endCircleColor = array.getColor(R.styleable.ProgressView_endCircleColor, Color.parseColor('#4fc1e9')); edgeDistance = array.getDimension(R.styleable.ProgressView_edgeDistance, 12); currentPercent = array.getFloat(R.styleable.ProgressView_currentPercent, 0); if(currentPercent>1||currentPercent<0){ currentPercent = currentPercent>1?1:0; } //初始化畫筆 backCirclePaint = new Paint(); backCirclePaint.setAntiAlias(true); backCirclePaint.setStrokeWidth(backCircleWidth); backCirclePaint.setColor(backCircleColor); backCirclePaint.setStyle(Paint.Style.STROKE); outerCirclePaint = new Paint(); outerCirclePaint.setAntiAlias(true); outerCirclePaint.setStrokeWidth(outerCircleWidth); outerCirclePaint.setColor(outerCircleColor); outerCirclePaint.setStyle(Paint.Style.STROKE); endBigCirclePaint = new Paint(); endBigCirclePaint.setAntiAlias(true); endBigCirclePaint.setStrokeWidth(endCircleWidth); endBigCirclePaint.setColor(endCircleColor); endBigCirclePaint.setStyle(Paint.Style.STROKE); endSmallCirclePaint = new Paint(); endSmallCirclePaint.setAntiAlias(true); endSmallCirclePaint.setColor(Color.WHITE); endSmallCirclePaint.setStyle(Paint.Style.FILL); titlePaint = new Paint(); //通過設置Flag來應用抗鋸齒效果 titlePaint.setFlags(Paint.ANTI_ALIAS_FLAG); titlePaint.setAntiAlias(true); //設置文字居中 //titlePaint.setTextAlign(Paint.Align.CENTER); titlePaint.setColor(titleTextColor); titlePaint.setTextSize(titleTextsize); numPaint = new Paint(); numPaint.setAntiAlias(true); numPaint.setFlags(Paint.ANTI_ALIAS_FLAG); //設置文字居中 //numPaint.setTextAlign(Paint.Align.CENTER); numPaint.setColor(numTextColor); numPaint.setTextSize(numTextsize); unitPaint = new Paint(); unitPaint.setAntiAlias(true); unitPaint.setFlags(Paint.ANTI_ALIAS_FLAG); //unitPaint.setTextAlign(Paint.Align.CENTER); unitPaint.setColor(unitTextColor); unitPaint.setTextSize(unitTextsize); //釋放 array.recycle(); }}

3.獲取組件高度寬度,重寫onMeasure方法

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); ///獲取總寬度,是包含padding值 //處理WAP_CONTENT int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); width = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); height = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) { //默認大小 200*200 setMeasuredDimension(200,200); }else if (widthSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(height, height); }else if (heightSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(width, width); } }

4.重寫onDraw()繪制組件各部分

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //圓心 int centerX = width / 2; int centerY = height / 2; //計算半徑 float radius = centerX - edgeDistance; //畫背景圓 drawBackCircle(canvas,centerX,centerY,radius); //繪制圓弧進度 drawProgress(canvas,centerX,centerY); //繪制標題 drawText(canvas); }```

###### 4.1繪制背景圓

```java /** * 繪制背景圓 * @param canvas * @param x 圓心位置x * @param y 圓心位置y * @param radius 半徑 */ private void drawBackCircle(Canvas canvas,int x,int y,float radius){ canvas.drawCircle(x,y,radius,backCirclePaint); }

4.2 繪制圓弧進度

1.注意:圓弧上端點進度為0或者100不顯示,此外端點的位置使用sin和cos來確定坐標;

Android自定義View實現圓弧進度的效果

/** * 繪制圓弧進度 */ private void drawProgress(Canvas canvas,int x,int y){ //圓弧的范圍 RectF rectF = new RectF(edgeDistance, edgeDistance, width - edgeDistance, height - edgeDistance); //定義的圓弧的形狀和大小的范圍 // 置圓弧是從哪個角度來順時針繪畫的 //設置圓弧掃過的角度 //設置我們的圓弧在繪畫的時候,是否經過圓形 這里不需要 //畫筆 canvas.drawArc(rectF, -90, 360 * currentPercent, false, outerCirclePaint); //繪制端圓 //進度在0~100%的時候才會畫終點小圓,可以自由改動 if(currentPercent>0&&currentPercent<1){ //繪制外層大圓 canvas.drawCircle(x + rectF.width() / 2 * (float) Math.sin(360 * currentPercent * Math.PI / 180), y - rectF.width() / 2 * (float) Math.cos(360 * currentPercent * Math.PI / 180), endCircleWidth / 2, endBigCirclePaint); //繪制內層圓點 canvas.drawCircle(x + rectF.width() / 2 * (float) Math.sin(360 * currentPercent * Math.PI / 180), y - rectF.width() / 2 * (float) Math.cos(360 * currentPercent * Math.PI / 180), endCircleWidth / 4, endSmallCirclePaint); } }

4.3 繪制文字

/** * 繪制標題 * @param canvas */ private void drawText(Canvas canvas) { Rect textRect = new Rect(); //返回的則是當前文本所需要的最小寬度,也就是整個文本外切矩形的寬度 titlePaint.getTextBounds(title, 0, title.length(), textRect);//25 50 175 //高度平分四部分 float h = height/ 4; //文字居中 canvas.drawText(title, width / 2 - textRect.width() / 2, h + textRect.height() / 2, titlePaint); numPaint.getTextBounds(num, 0, num.length(), textRect); canvas.drawText(num, width / 2 - textRect.width() / 2, h*2 + textRect.height() / 2, numPaint); unitPaint.getTextBounds(unit, 0, unit.length(), textRect); canvas.drawText(unit, width / 2 - textRect.width() / 2, 3*h + textRect.height() / 2, unitPaint); }

4.4提供外部修改進度方法以及進度過度

/** * 設置進度 */ public void setProgress(final float progress){ new Thread(new Runnable() { @Override public void run() { for(int i=0;i<=progress*100;i++){ Message msg = new Message(); msg.what = 1; msg.obj = i; try { Thread.sleep(20); handler.sendMessage(msg); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } private Handler handler = new Handler(new Handler.Callback(){ @Override public boolean handleMessage(@NonNull Message msg) { if(msg.what==1){ currentPercent = ((float)Integer.valueOf(msg.obj+'')/100); System.out.println('更新'+currentPercent); invalidate(); } return false; } });

總結:使用Canvas的drawArc方法繪制圓弧及drawText繪制文本信息等;

github地址:項目地址

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Android
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99在线|亚洲一区二区| 日韩久久一区二区三区| 久久青草久久| 日韩免费在线| 亚洲精品国产嫩草在线观看| 亚洲精品一区三区三区在线观看| 欧洲av不卡| 精品一区三区| 视频在线观看国产精品| 色综合视频一区二区三区日韩 | 亚洲性色视频| 国产成人精品一区二区三区视频 | 蜜桃视频第一区免费观看| 三级久久三级久久久| 欧美精品国产| 久久女人天堂| 91精品一区二区三区综合在线爱| 亚洲国产专区校园欧美| 在线亚洲免费| 欧美一区二区三区久久| 久久wwww| 高潮一区二区| 伊人久久婷婷| 亚洲人成网77777色在线播放| 日韩动漫一区| 国产在线观看91一区二区三区| 免费一二一二在线视频| 五月综合激情| 日本亚洲三级在线| 国产精品xxx| 日韩国产专区| 中文字幕中文字幕精品| 国产精品超碰| 欧美国产91| 日韩一区二区三区精品 | 久久婷婷一区| 免费久久精品视频| 麻豆精品国产91久久久久久| 视频福利一区| 亚洲精品激情| av在线资源| 免费久久99精品国产| 国产精品乱战久久久| 91精品国产调教在线观看| 亚洲精品伊人| 夜鲁夜鲁夜鲁视频在线播放| 亚洲另类av| 日韩激情一区| 一本综合精品| 高清一区二区| 热久久国产精品| 水蜜桃久久夜色精品一区| 午夜在线视频一区二区区别| 精品国产亚洲日本| 日韩精品一级中文字幕精品视频免费观看| 麻豆视频一区二区| 蜜臀va亚洲va欧美va天堂 | 97精品中文字幕| 亚洲有吗中文字幕| 香蕉视频亚洲一级| 久久精品99国产国产精| 久久中文字幕av| 91精品国产自产观看在线| 久久久国产亚洲精品| 国产亚洲精品美女久久| 欧美日韩国产在线一区| 国精品产品一区| 日本在线视频一区二区| 99精品视频在线| 精品国产乱码| 日本va欧美va精品发布| 欧美天堂亚洲电影院在线观看| 精品国产美女a久久9999| 亚洲精品高潮| 亚洲午夜在线| 在线看片福利| 国产欧美日韩精品一区二区免费| 精品在线91| 色欧美自拍视频| 777久久精品| 亚洲自啪免费| 久久久久久免费视频| 美女精品久久| 日本中文字幕一区二区| 国产精品美女久久久浪潮软件| 日韩国产专区| 精品久久在线| 国产精品tv| 日韩不卡免费视频| 亚洲深夜av| 99免费精品| 欧美激情 亚洲a∨综合| 日韩综合一区二区三区| 三级欧美韩日大片在线看| 婷婷精品进入| 麻豆网站免费在线观看| 欧美a一区二区| 欧美日本二区| 91亚洲精品视频在线观看| 免费久久99精品国产| 激情婷婷综合| 天堂日韩电影| 精品欧美一区二区三区在线观看| 精品久久久中文字幕| 欧美国产三级| 国产精品久久久网站| 天海翼精品一区二区三区| 黄色亚洲精品| 尹人成人综合网| 欧美~级网站不卡| 三级精品视频| 成人污污视频| 91亚洲成人| 黄在线观看免费网站ktv| 国产一区二区三区天码| 精品一区二区三区中文字幕| 另类综合日韩欧美亚洲| 欧美精品二区| 国内精品麻豆美女在线播放视频| 精品久久久亚洲| 成人精品国产亚洲| 91亚洲国产成人久久精品| 精品国产麻豆| 中文一区一区三区高中清不卡免费| 久久中文字幕导航| 精品国产精品国产偷麻豆 | 国产女优一区| 蜜臀国产一区二区三区在线播放 | 尤物在线精品| 蜜桃av一区| 亚洲精品在线二区| 免费人成精品欧美精品| 日本精品在线播放| 国产精品高清一区二区| 国产一区二区三区四区大秀| 欧美sm一区| 中国女人久久久| 日韩视频1区| 久久精品免视看国产成人| 免费看av不卡| 午夜精品免费| 日韩精品一区二区三区av| 国产精品一区免费在线| 国产一区二区三区不卡av | 黄色aa久久| 久久精品青草| 亚洲人成精品久久久| 国产精品啊v在线| 成人午夜精品| 樱桃成人精品视频在线播放| 日韩激情一二三区| 精品视频自拍| 91精品久久久久久久久久不卡| 免费精品视频| 国产精品蜜月aⅴ在线| 国产精品久久久久久久久久10秀 | 美国三级日本三级久久99| 亚洲精品动态| 久久99视频| 国产二区精品| 欧美一区=区三区| 四虎国产精品免费观看| 欧美91视频| 欧美一级网址| 精品免费av在线| 亚洲精品无吗| 日本一区二区免费高清| 在线国产一区二区| 国产日韩一区| 999国产精品| 欧美日韩一区二区三区不卡视频| 欧美男人天堂| 老鸭窝毛片一区二区三区| 国产三级一区| 欧美一区二区三区激情视频| 亚洲精品在线国产| 国产一区2区| 石原莉奈在线亚洲二区| 国产在线日韩精品| 亚洲精选av| 欧美日韩在线观看首页| 日韩精品视频在线看| 日本久久成人网| 国产一卡不卡| 成人av二区| 麻豆一区二区99久久久久| 日韩午夜免费| 国产一区二区三区日韩精品| 首页国产欧美久久| 樱桃视频成人在线观看| 日韩手机在线| 99精品视频在线| 国产精品igao视频网网址不卡日韩 | 日韩理论片av| 国产精品一页| 日韩一区二区三区免费视频| 亚洲一区有码| 国产亚洲永久域名| 国产一区二区三区天码| 蜜桃久久久久久|