Android view自定義實現(xiàn)動態(tài)進(jìn)度條
Android 自定義view實現(xiàn)動態(tài)進(jìn)度條
效果圖:
這個是看了梁肖的demo,根據(jù)他的思路自己寫了一個,但是我寫的這個貌似計算還是有些問題,從上面的圖就可以看出來,左側(cè)、頂部、右側(cè)的線會有被截掉的部分,有懂得希望能給說一下,改進(jìn)一下,這個過程還是有點曲折的,不過還是覺得收獲挺多的。比如通動畫來進(jìn)行動態(tài)的展示(之前做的都是通過Handler進(jìn)行更新的所以現(xiàn)在換一種思路覺得特別好),還有圓弧的起止角度,矩形區(qū)域的計算等!關(guān)于繪制我們可以循序漸進(jìn),比如最開始先畫圓,然后再畫周圍的線,最后設(shè)置動畫部分就可以了。不多說了,上代碼了。
代碼
自定義View
public class ColorProgressBar extends View{
//下面這兩行在本demo中沒什么用,只是前幾天看別人的代碼時學(xué)到的按一定尺寸,設(shè)置其他尺寸的方式,自動忽略或者學(xué)習(xí)一下也不錯
// private int defaultStepIndicatorNum= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40,getResources().getDisplayMetrics());
// int mCircleRadius=0.28f*defaultStepIndicatorNum;
//布局的寬高
private int mWidth;
private int mHeight;
//直徑
private int mDiameter=500;
//底層圓畫筆
private Paint mPaintbg;
//頂層圓的畫筆
private Paint mPaintft;
//周圍線的畫筆
private Paint mPaintLine;
//外層線條的長度
private int mLongItem=dip2px(20);
//線條與圓的間距
private int mDistanceItem=dip2px(10);
//進(jìn)度條的最大寬度(取底層進(jìn)度條與頂層進(jìn)度條寬度最大的)
private int mProgressWidth;
//底層圓的顏色
private int mBackColor;
//頂層圓的顏色
private int mFrontColor;
//底層圓、頂層圓的寬度
private float mBackWidth;
private float mFrontWidth;
//設(shè)置進(jìn)度
private float currentvalue;
//通過動畫演示進(jìn)度
private ValueAnimator animator;
private int curvalue;
public ColorProgressBar(Context context) {
this(context,null,0);
}
public ColorProgressBar(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public ColorProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.ColorProgressBar);
mBackColor= ta.getColor(R.styleable.ColorProgressBar_back_color, Color.BLACK);
mFrontColor=ta.getColor(R.styleable.ColorProgressBar_front_color,mBackColor);
mBackWidth=ta.getDimension(R.styleable.ColorProgressBar_back_width,dip2px(10));
mFrontWidth=ta.getDimension(R.styleable.ColorProgressBar_front_width,dip2px(10));
mProgressWidth=mBackWidth>mFrontWidth?(int)mBackWidth:(int)mFrontWidth;
//注意釋放資源
ta.recycle();
init();
}
/**
* 都是畫筆初始化
*/
private void init() {
mPaintbg=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintbg.setStrokeWidth(mProgressWidth);
mPaintbg.setColor(mBackColor);
mPaintbg.setStrokeCap(Paint.Cap.ROUND);
mPaintbg.setStyle(Paint.Style.STROKE);
mPaintft=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintft.setColor(mFrontColor);
mPaintft.setStyle(Paint.Style.STROKE);
mPaintft.setStrokeWidth(mFrontWidth);
mPaintft.setStrokeCap(Paint.Cap.ROUND);
mPaintLine=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintLine.setColor(Color.BLACK);
mPaintLine.setStrokeWidth(5);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 寬度=高度=(長指針+指針與圓盤的間距+進(jìn)度條的粗細(xì)+半徑)*2
Log.e("測量數(shù)據(jù)","LongItem:"+mLongItem+"mDistanceItem:"+mDistanceItem+"mProgressWidth:"+mProgressWidth+"mDiameter:"+mDiameter/2);
mWidth=(int)2*(mLongItem+mDistanceItem+mProgressWidth*2+mDiameter/2);
mHeight=(int)2*(mLongItem+mDistanceItem+mProgressWidth*2+mDiameter/2);
Log.e("自定義View","高度"+mHeight+"寬度"+mWidth);
setMeasuredDimension(mWidth,mHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//繪制底層圓弧,矩形的具體計算見圖片
canvas.drawArc(new RectF(mProgressWidth/2+mDistanceItem+mLongItem,mProgressWidth/2+mDistanceItem+mLongItem,mWidth-mProgressWidth/2-mDistanceItem-mLongItem,mHeight-mProgressWidth/2-mDistanceItem-mLongItem),0,360,true,mPaintbg);
// SweepGradient gradient=new SweepGradient();
//繪制邊緣線
canvas.save();
canvas.rotate(144,mWidth/2,mHeight/2);
for(int i=0;i<=30;i++){
canvas.rotate(-9,mWidth/2,mHeight/2);
if(i%5==0){
canvas.drawLine(mWidth/2,5,mWidth/2,mLongItem,mPaintbg);
}else {
canvas.drawLine(mWidth/2,25,mWidth/2,mLongItem,mPaintLine);
}
}
canvas.restore();
//給畫筆設(shè)置漸變
SweepGradient sweepGradient=new SweepGradient(mWidth/2,mHeight/2,Color.RED,Color.YELLOW);
mPaintft.setShader(sweepGradient);
//繪制頂層圓弧,currentvalue在改變時呈現(xiàn)動態(tài)效果
canvas.drawArc(new RectF(mProgressWidth/2+mDistanceItem+mLongItem,mProgressWidth/2+mDistanceItem+mLongItem,mWidth-mProgressWidth/2-mDistanceItem-mLongItem,mHeight-mProgressWidth/2-mDistanceItem-mLongItem),135,currentvalue,false,mPaintft);
mPaintft.setTextSize(100);
mPaintft.setTextAlign(Paint.Align.CENTER);
//繪制文本
canvas.drawText(String.format("%.0f",currentvalue),mWidth/2,mHeight/2+50,mPaintft);
invalidate();
}
/**
* 設(shè)置動畫
* @param value
*/
public void setCurrentValue(float value){
// currentvalue=value;
animator=ValueAnimator.ofFloat(currentvalue,value);
animator.setDuration(3000);
animator.setTarget(currentvalue);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
currentvalue= (float) valueAnimator.getAnimatedValue();
curvalue=curvalue/10;
}
});
animator.start();
}
private int dip2px(float dip){
float density=getContext().getResources().getDisplayMetrics().density;
return (int)(dip*density+0.5f);
}
}
矩形計算

Activity調(diào)用
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.colorprogressbar);
mBtStart1= (Button) findViewById(R.id.bt1);
bar1= (ColorProgressBar) findViewById(R.id.cp1);
mBtStart1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bar1.setCurrentValue(270);
}
});
}
自定義屬性
<declare-styleable name="ColorProgressBar">
<attr name="back_color" format="color"></attr>
<attr name="front_color" format="color"></attr>
<attr name="back_width" format="dimension"></attr>
<attr name="front_width" format="dimension"></attr>
</declare-styleable>
布局
注意:為了使用自定義屬性需要添加一行代碼(AS)
xmlns:app=http://schemas.android.com/apk/res-auto
布局
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start1"/>
<com.demo.demo.networkdemo.colorprogressbar.widget.ColorProgressBar
android:id="@+id/cp1"
android:layout_width="232dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
app:back_color="@color/colorPrimary"
app:front_color="@color/colorAccent"
android:background="@mipmap/ic_launcher"/>
</LinearLayout>
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
Android實現(xiàn)聯(lián)動下拉框二級地市聯(lián)動下拉框功能
這篇文章主要介紹了Android實現(xiàn)聯(lián)動下拉框二級地市聯(lián)動下拉框功能,本文給大家分享思路步驟,給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2018-12-12
Android自定義ViewGroup實現(xiàn)朋友圈九宮格控件
在我們的實際應(yīng)用中,經(jīng)常需要用到自定義控件,比如自定義圓形頭像,自定義計步器等等,這篇文章主要給大家介紹了關(guān)于Android自定義ViewGroup實現(xiàn)朋友圈九宮格控件的相關(guān)資料,需要的朋友可以參考下2021-07-07
WorkManager解決應(yīng)用退出后繼續(xù)運行后臺任務(wù)
這篇文章主要為大家介紹了WorkManager解決應(yīng)用退出后繼續(xù)運行后臺任務(wù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
簡單掌握Android開發(fā)中彩信的發(fā)送接收及其附件的處理
這篇文章主要介紹了簡單掌握Android開發(fā)中彩信的發(fā)送接收及其附件的處理,由于微信的流行,使用彩信的用戶已經(jīng)很少了,簡單了解即可,需要的朋友可以參考下2016-02-02
淺談Android系統(tǒng)的基本體系結(jié)構(gòu)與內(nèi)存管理優(yōu)化
這篇文章主要介紹了Android系統(tǒng)的基本體系結(jié)構(gòu)與內(nèi)存管理優(yōu)化,非常簡潔明了地總結(jié)了系統(tǒng)服務(wù)及垃圾回收等安卓的一些主要特性,需要的朋友可以參考下2016-02-02
淺析Android位置權(quán)限以及數(shù)組尋找索引的坑
這篇文章給大家分享了Android位置權(quán)限以及數(shù)組尋找索引的坑的相關(guān)知識點內(nèi)容,有興趣的朋友可以參考學(xué)習(xí)下。2018-07-07
Android處理圖像數(shù)據(jù)轉(zhuǎn)換的各種方法
這篇文章主要介紹了Android處理圖像數(shù)據(jù)轉(zhuǎn)換的各種方法,本文講解了RGB值轉(zhuǎn)Bitmap、Color值轉(zhuǎn)Bitmap、字節(jié)數(shù)組轉(zhuǎn)Bitmap、讀取文件轉(zhuǎn)Bitmap、讀取資源轉(zhuǎn)Bitmap、輸入流轉(zhuǎn)Bitmap等內(nèi)容,需要的朋友可以參考下2015-01-01

