開發中常常須要自定義ProgressBar,這裏用了自定義View和ClipDrawable實現簡單的ProgressBar
自定義View效果:java
public class CustomProgressBar extends View { private Paint mBgtPaint;//底部背景畫筆 private Paint mProgressPaint;//progress畫筆 private int startX;//起始X座標,保持不變 private int endX;//終點座標,保持不變 private int currentX;//當前座標,progress換算而來,不斷增大 private int mProgressBgHeight = 60; private int mProgressHeight = 50; private int mProgressBgColor = Color.BLACK; private int mProgressColor = Color.BLUE; public CustomProgressBar(Context context){ this(context, null); } public CustomProgressBar(Context context, @Nullable AttributeSet attrs){ this(context, attrs, 0); } public CustomProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr){ super(context, attrs, defStyleAttr); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.myProgressBar, defStyleAttr, 0); mProgressBgHeight = a.getInteger(R.styleable.myProgressBar_progress_background_height, mProgressBgHeight); mProgressHeight = a.getInteger(R.styleable.myProgressBar_progress_height,mProgressHeight); mProgressBgColor = a.getColor(R.styleable.myProgressBar_progress_background_color,mProgressBgColor); mProgressColor = a.getColor(R.styleable.myProgressBar_progress_color, mProgressColor); a.recycle(); init(); } private void init() { //初始化畫筆 mBgtPaint = new Paint(); mBgtPaint.setAntiAlias(true);//抗鋸齒 mBgtPaint.setStyle(Paint.Style.STROKE); //注意:這是筆尖樣式的屬性,Paint.Cap.ROUND設置筆尖爲圓形,默認方形, mBgtPaint.setStrokeCap(Paint.Cap.ROUND); mBgtPaint.setColor(mProgressBgColor); // mBgtPaint.setColor(Color.parseColor("#1F1F26"));//設置畫筆顏色,這裏是深灰色 mBgtPaint.setStrokeWidth(60); mProgressPaint = new Paint(); mProgressPaint.setAntiAlias(true); mProgressPaint.setStyle(Paint.Style.STROKE); mProgressPaint.setStrokeCap(Paint.Cap.ROUND); mProgressPaint.setColor(mProgressColor); // mProgressPaint.setColor(Color.parseColor("#54FC00")); mProgressPaint.setStrokeWidth(50);//這裏的線條寬度比背景線條窄一些。 } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); //這裏根據屏幕的寬高獲取座標,能夠設置成自定義屬性,讓用戶設置 startX = getWidth()/2-getWidth()/3; endX = getWidth()/2 + getWidth()/3; currentX = startX; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //繪製底部背景線條(深灰色,區別於View背景色) canvas.drawLine(startX, getHeight() / 2, endX, getHeight() / 2, mBgtPaint); //繪製當前的progress canvas.drawLine(startX+1, getHeight() / 2, currentX, getHeight() / 2, mProgressPaint); } //更新進度 public void updateProgress(int progress) { //這裏progress的長度分紅100個單位,再計算座標,其實progress能夠是實時的下載進度, //計算下載量百分比,而後再計算座標,會相對精確 if (progress <= 100){ currentX = startX + (int)((progress * 1.0)/100 * (endX - startX)); invalidate();//從新繪製才能生效 } } }
使用到了自定義的屬性,能夠在values/下添加attrs.xml(文件能夠爲其餘名字),res/values/attrs.xmlandroid
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="myProgressBar"> <attr name="progress_background_color" format="color"/> <attr name="progress_background_height" format="integer"/> <attr name="progress_color" format="color"/> <attr name="progress_height" format="integer"/> </declare-styleable> </resources>
代碼中使用:canvas
public class CustomActivity extends AppCompatActivity { private CustomProgressBar mCustomProgressBar; private int mProgress=0; private Handler mHandler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom); mCustomProgressBar = (CustomProgressBar)findViewById(R.id.progress_bar_custom); mHandler.postDelayed(new Runnable() { @Override public void run() { mCustomProgressBar.updateProgress(++mProgress); if (mProgress < 100) { mHandler.postDelayed(this, 500); } } }, 500); } }
這樣大部分的自定義的ProgressBar均可以畫出來,有些可能須要添加動畫。若是有些ProgressBar自己的樣式
太過複雜,使用自定義view畫出來有較大的難度,那麼還有更簡單的方法,讓ui切出ProgressBar完整的圖片,而後使用ClipDrawable根據
進度的更新不斷地顯示,使用起來其實挺簡單的,效果圖:app
先定義一個clipDrawableide
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:clipOrientation="horizontal" android:drawable="@drawable/gakki_alone" android:gravity="left"/>
第一個屬性:裁剪方向,這裏是水平方向。第二個參數:圖片,第三個參數:開始裁剪的位置,這裏是從左開始佈局
xml佈局中使用,和普通的drawable使用方法同樣post
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.why.traing2.ClipDrawableActivity"> <ImageView android:id="@+id/img_clip" android:layout_width="300dp" android:layout_height="300dp" android:scaleType="centerCrop" android:background="@color/colorAccent" android:src="@drawable/clip" android:layout_centerInParent="true"/> </FrameLayout>
最後是代碼中的的引用動畫
public class ClipDrawableActivity extends AppCompatActivity { private Handler mHandler = new Handler(); private int mLevel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_clip_drawable); ImageView imageView = (ImageView)findViewById(R.id.img_clip); final ClipDrawable clipDrawable = (ClipDrawable)imageView.getDrawable(); //level取值:0-10000, 0:不可見,10000:徹底顯示 mLevel = clipDrawable.getLevel(); mHandler.postDelayed(new Runnable() { @Override public void run() { clipDrawable.setLevel(mLevel); mLevel += 100; if (mLevel <= 10000) { mHandler.postDelayed(this, 500); } } }, 500); } }
這樣複雜的ProgressBar, 能夠直接使用圖片按比例顯示讀取進度,節省代碼量.ui