拒絕第三方--手把手教你自定義進度條
還在為了一個小小的效果,依賴一個一個的第三方?
看著別人隨隨便便寫了一個自定義效果,自己卻除了666啥也做不了?
如果你認為自己就是這樣,那麼,你要好好看一下這篇文章了!
進度條作為移動開發的一個常用功能,相信你一定不陌生。本篇,我們要手動編寫一個簡單的進度條,模擬一下下載的效果。
一、效果
二、分析
自定義View,分析裡面的元素:
1、進度條背景顏色
2、進度條背景是否是實心
3、進度條的顏色
4、進度(文字)的顏色和字型大小
5、進度條的圓角大小
三、實現
1、自定義View類,繼承View
public class CustomProgressView extends View { public CustomProgressView(Context context) { this(context, null); } public CustomProgressView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public CustomProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
2、在attr檔案中,定義樣式
<declare-styleable name="CustomProgressView"> <!--百分比文字大小--> <attr name="cp_percent_textsize" format="dimension"/> <!--百分比文字顏色--> <attr name="cp_percent_textcolor" format="color|integer"/> <!--進度條背景顏色--> <attr name="cp_background_color" format="color|integer"/> <!--進度條背景是否空心--> <attr name="cp_background_is_stroke" format="boolean"/> <!--進度條顏色--> <attr name="cp_progress_color" format="color|integer"/> <!--進度條圓角值--> <attr name="cp_rect_round" format="dimension"/> </declare-styleable>
定義元素,並賦予正確的屬性型別。
3、在構造方法中,呼叫obtainStyledAttributes方法,獲取自定義的style,並初始化個屬性,同時,初始化畫筆Paint
private int cp_percent_textsize = 18;//百分比字型大小 private int cp_percent_textcolor = 0xff009ACD; private int cp_background_color = 0xff636363; private int cp_progress_color = 0xff00C5CD; private boolean cp_background_is_stroke = true; private int cp_rect_round = 5; private Paint mPaint; private int mCenterX; private int mCenterY; private int progressCurrent = 0; private int progressMax = 100; public CustomProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(R.styleable.CustomProgressView); cp_percent_textsize = (int) typedArray.getDimension(R.styleable.CustomProgressView_cp_percent_textsize, cp_percent_textsize); cp_percent_textcolor = typedArray.getColor(R.styleable.CustomProgressView_cp_percent_textcolor, cp_percent_textcolor); cp_background_color = typedArray.getColor(R.styleable.CustomProgressView_cp_background_color, cp_background_color); cp_progress_color = typedArray.getColor(R.styleable.CustomProgressView_cp_progress_color, cp_progress_color); cp_background_is_stroke = typedArray.getBoolean(R.styleable.CustomProgressView_cp_background_is_stroke, cp_background_is_stroke); cp_rect_round = (int) typedArray.getDimension(R.styleable.CustomProgressView_cp_rect_round, cp_rect_round); typedArray.recycle(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); }
4、複寫最重要的方法onDraw
@Override
protected void onDraw(Canvas canvas) {
mCenterX = getWidth() / 2;
mCenterY = getHeight() / 2;
drawHorProgress(mPaint, canvas);
}
private void drawHorProgress(Paint paint, Canvas canvas) {
//畫背景
paint.setColor(cp_background_color);
if (cp_background_is_stroke) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
} else {
paint.setStyle(Paint.Style.FILL);
}
canvas.drawRoundRect(new RectF(mCenterX - getWidth() / 2, mCenterY - getHeight() / 2,
mCenterX + getWidth() / 2, mCenterY + getHeight() / 2), cp_rect_round, cp_rect_round, paint);
//畫進度條
paint.setColor(cp_progress_color);
paint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(new RectF(mCenterX - getWidth() / 2, mCenterY - getHeight() / 2,
(int) (progressCurrent * getWidth() / progressMax), mCenterY + getHeight() / 2), cp_rect_round, cp_rect_round, paint);
//畫文字
paint.setColor(cp_percent_textcolor);
paint.setTextSize(cp_percent_textsize);
paint.setStyle(Paint.Style.FILL);
String value_str = (int) (progressCurrent * 100 / progressMax) + "%";
Rect rect = new Rect();
paint.getTextBounds(value_str, 0, value_str.length(), rect);
float textWidth = rect.width();
float textHeight = rect.height();
if (textWidth >= getWidth()) {
textWidth = getWidth();
}
Paint.FontMetrics metrics = paint.getFontMetrics();
float baseline = (getMeasuredHeight() - metrics.bottom + metrics.top) / 2 - metrics.top;
canvas.drawText(value_str, mCenterX - textWidth / 2, baseline, paint);
}
步驟:
1、想一下,其實很簡單。
進度條背景和進度條,就是兩個圓角矩形疊加在一起。最後再把文字畫在矩形的中間位置。
2、找到View的中心點,getWidth / 2 , getHeight / 2。
3、畫背景。
其實背景很簡單。固定的圓角矩形。left、top、right、bottom座標其實是固定的。根據中心點,很容易畫出來。
4、畫進度條。
進度條是根據的進度值的變化實時重新整理的。所以我們要定義一個當前進度progressCurrent和最大進度progressMax。
為什麼要定義最大進度?實際生產中,你要根據下載檔案的總大小和當前已經下載的大小來計算進度,所以這個是要設定的。
仔細分析,可以知道,在你畫進度條的時候,其實只有一個座標值是變化的,那就是 right 。你可以根據當前進度的百分比來計算當前精度下的 right 佔寬度的多少比例。
5、畫文字
使文字居中的baseline是一個知識點,需要重點掌握。
6、給各屬性值設定setter和getter方法。
這裡主要說一下,進度值的設定。
public int getProgressCurrent() {
return progressCurrent;
}
public void setProgressCurrent(int progressCurrent) {
if (progressCurrent > progressMax) {
this.progressCurrent = progressMax;
} else {
this.progressCurrent = progressCurrent;
}
postInvalidate();
}
噹噹前進度超過最大進度時,當前進度設定為最大進度。(當前進度為100%的下一秒,就會出現超過最大進度的情況)
記得重新繪製View 呼叫postInvalidate();方法。
5、佈局
<net.feelingtech.example_work.custom.ownprogress.CustomProgressView
android:id="@+id/cpv_one"
android:layout_width="match_parent"
android:layout_height="15dp" />
6、跑起來
mCustomProgressView = view.findViewById(R.id.cpv_one);
mCustomProgressView.setProgressMax(100);
mCustomProgressView.setCp_background_color(Color.parseColor("#A2CD5A"));
mCustomProgressView.setCp_percent_textcolor(Color.RED);
mCustomProgressView.setCp_rect_round(16);
mCustomProgressView.setCp_background_is_stroke(false);
mCustomProgressView.setCp_percent_textsize(30);
view.findViewById(R.id.bt_start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (progressCurrent != 0) {
progressCurrent = 0;
return;
}
mRunnable = new Runnable() {
@Override
public void run() {
progressCurrent += 1;
mCustomProgressView.setProgressCurrent(progressCurrent);
mHandler.postDelayed(mRunnable, 5);
}
};
mHandler.postDelayed(mRunnable, 1);
}
});
OVER ! ! !
掃碼關注,共同進步
相關推薦
拒絕第三方--手把手教你自定義進度條
還在為了一個小小的效果,依賴一個一個的第三方? 看著別人隨隨便便寫了一個自定義效果,自己卻除了666啥也做不了? 如果你認為自己就是這樣,那麼,你要好好看一下這篇文章了! 進度條作為移動開發的一個常用功能,相信你一定不陌生。本篇,我們要手動編寫一個簡單的進度條,模擬一下
[C#] (原創)一步一步教你自定義控制元件——04,ProgressBar(進度條)
一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:進度條(ProgressBar)。 進度條的實現方式多種多樣,主流的方式有:使用多張圖片去實現、使用1個或2個Panel放到UserControl上去實現、過載系統進度條去實現等等。 本次所實現的進度條仍是使用GDI+去實現。當然,如果
Android 手把手教您自定義ViewGroup 一
最近由於工作的變動,導致的部落格的更新計劃有點被打亂,希望可以儘快脈動回來~今天給大家帶來一篇自定義ViewGroup的教程,說白了,就是教大家如何自定義ViewGroup,如果你對自定義ViewGroup還不是很瞭解,或者正想學習如何自定義,那麼你可以好好看看這篇部落格。1、
Android 手把手教您自定義ViewGroup(一)
最近由於工作的變動,導致的部落格的更新計劃有點被打亂,希望可以儘快脈動回來~今天給大家帶來一篇自定義ViewGroup的教程,說白了,就是教大家如何自定義ViewGroup,如果你對自定義ViewGroup還不是很瞭解,或者正想學習如何自定義,那麼你可以好好看看這篇部落格。1、概述在寫程式碼之前,我必須得
IOS-一步一步教你自定義評分星級條RatingBar
// RatingBar.m // // Created by HailongHan on 15/1/1. // Copyright (c) 2015年 cubead. All rights reserved. // #import "RatingBar.h" @interface RatingBar
[C#] (原創)一步一步教你自定義控制元件——02,ScrollBar(滾動條)
一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:滾動條(ScollBar)。 我們可以在網上看到很多自定義的滾動條控制元件,它們大都是使用UserControl去做,即至少使用一個Panel或其它控制元件作滑塊,使用UserControl本身或另一個控制元件作為背景條,而有的複雜的還
[C#] (原創)一步一步教你自定義控制元件——03,SwitchButton(開關按鈕)
一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:開關按鈕(SwitchButton)。 開關按鈕非常簡單,實現方式也多種多樣,比如常見的:使用兩張不同的按鈕圖片,代表開和關,然後在點選時切換這兩張圖片。 而本篇和前兩篇一脈相承,都是繼承Control,使用GDI+去實現。因為都是相同
[C#] (原創)一步一步教你自定義控制元件——05,Label(原生控制元件)
一、前言 技術沒有先進與落後,只有合適與不合適。 自定義控制元件可以分為三類: 一類是“無中生有”。就如之前文章中的的那些控制元件,都是繼承基類Control,來實現特定的功能效果; 一類是“有則改之”。是對原生控制元件的改造,以達到特定的功能效果; 一類是“使用者控制元件”。是將多個控制元件進行組合,以實現
[C#] (原創)一步一步教你自定義控制元件——06,MaskLayer(遮罩層)
一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:遮罩層(MaskLayer)。 遮罩層對軟體的美觀與易用性上的提高是很大的,在日常使用過程中也會經常看到各種遮罩層,雖然WinForm本身沒有原生的遮罩層控制元件,但實現起來並不麻煩。 遮罩層的實現方式一般有兩種:一種是基於自定義控制元
【專案實踐】手把手教你自建高效能物件儲存伺服器
![物件儲存.png](https://img2020.cnblogs.com/blog/1496775/202103/1496775-20210310095045009-259334496.jpg) > 以專案驅動學習,以實踐檢驗真知 物件儲存的應用範圍非常廣泛,小至圖床、檔案服務,大至大資料應用。無論
aNDROID自定義進度條顏色
定義 hao123 自定義進度條 com list andro 顏色 androi baidu DIaLOGFRaGMENT%E9%97%AE%E9%A2%98%E6%B1%82%E8%A7%A3 http://music.baidu.com/songlist/49564
vue自定義進度條的製作方法(含css屬性值的兩種動態改變方式)
雛形部分接上一篇文章:https://blog.csdn.net/ColourfulTiger/article/details/82910505 結合vue製作自定義的進度條,優勢在於採用了vue特有的樣式繫結,與雙向繫結的方法,達到資料與進度條的進度一致。 突破點:通過變數來動態改變屬性對
C#自定義進度條,可用於音樂播放器進度調整,音量調整等功能
平時在做c#專案時偶爾會碰到要使用進度條的情況,但c#自帶的進度條外觀往往不合我們心意,這就需要我們自己動手來只做一款自己的進度條。先上圖: 外觀雖然簡單,但感覺比c#自帶的好看多了。 繪製這樣一個進度條需要兩個基本控制元件,兩個La
Android帶圓形數字進度的自定義進度條
開發 設計搞了一個帶圓形進度的進度條,在GitHub上逛了一圈,發現沒有,自己擼吧。 先看介面效果: 主要思路是寫一個繼承ProgressBar的自定義View,不廢話,直接上程式碼: package com.fun.progressbarwithn
Android 各種自定義進度條Progressbar
Android 自定義進度條 Progressbar 控制元件集合 Seekbar with labelled intervals Like Olx FilterView Seekbar Android-ProgressViews
自定義進度條之圓角進度條問題
Android自定義進度條是開發中比較常見的一個需求,在之前的部落格中也介紹過如何通過自定義ProgressBar的樣式來實現自定義水平進度條和環形進度條。本文主要是對近期一個專案中的圓角進度條的實現做一個記錄。 設計給出的圖是這樣的: 拿到設計圖,對於
Android-自定義View-自定義進度條
眼看6月到了,由於前段時間域名備案等原因,伺服器關閉了差不多一個月,所以沒更新文章,索性今天補一篇吧,準備寫一個簡單的自定義View,就拿進度條做這個需求吧,雖然簡單,但是也包含了基本自定義View的幾要素,比如自定義屬性、重寫測量、重寫繪製等功能。 需求
小程式視訊自定義進度條
大體思路:先在wxml檔案中定義一個進度條,然後在視訊上定義播放進度變化時觸發bindtimeupdate這個屬性,進而進度條值改變觸發sliderChanging()和sliderChange()方法。 1、定義進度條 <view class='process-
Android簡單自定義進度條(小白進)
今天,我在騰訊課堂學習了自定義一個進度條,視訊連結:https://ke.qq.com/course/144239#term_id=100163342,我根據此視訊教程,寫了關於此程式碼的詳細註釋,非常簡單,非常適合小白學習。 主要步驟是: 1.
Ftp上傳下載檔案,並能自定義進度條展示(FtpClient)
前一段時間,自己寫了一個java專案釋出在一個免費的java平臺上但是該平臺給專案的是虛擬路徑並不能上傳檔案。後來想到應用ftp作為上傳檔案的儲存器。 ftp上傳的工具類有sun(sun.net.*)和apache(org.apache.commons.net.ftp.*