进度条的样式有很多,大部分能够满足我们的需求,但是,不排除一些特别情况,比如:这个进度条太难看,换成这种这种..巴拉巴拉小魔仙什么的,所以,有时候就需要我们自己来处理了。
自定义动画,没什么好说的,重写View
/** * 圆形动画 * Created by IKL on 2018/6/6. */ public class RoundProgressBar extends View { /** * 圆环半径 */ private int mRadius = 93; // Diameter英文为直径,该常量表示小圆直径的dp值 /** * 圆环的宽度 */ private int mTrokeWidth = 40; /** * 起始角度 */ private int mStartAngle = 270; /** * 进度条进度颜色 */ private int mArcColor; private Paint mPaint; private int mProgress;// 表示进度 private RectF mRect; private int mDiameter; // Diameter英文为直径,在该View中要绘制圆环,圆环由两个圆形确定(大圆和小圆),这个整形值表示小圆直径。 private int mWidth;// 这个值表示圆环的宽度的2倍(大圆直径-小圆直径) private final int defaultColor; // 进度条背景颜色 public RoundProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); defaultColor = Color.TRANSPARENT; TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ArcProgressbar, defStyle, 0); int num = ta.getIndexCount(); for (int i = 0; i < num; i++) { int attr = ta.getIndex(i); switch (attr) { case R.styleable.ArcProgressbar_startAngle: mStartAngle = ta.getInt(attr, 135); break; case R.styleable.ArcProgressbar_arcColor: mArcColor = ta.getColor(attr, Color.parseColor("#eed306")); break; case R.styleable.ArcProgressbar_trokeWidth: mTrokeWidth = ta.getInt(attr, 15); break; } } init(); } public RoundProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundProgressBar(Context context) { this(context, null); } private void init() { Resources res = getResources(); // getDisplayMetrics()返回当前展示的metrics. DisplayMetrics metrics = res.getDisplayMetrics(); // TypedValue.applyDimension(int unit, float value, DisplayMetrics // metrics) // 该方法中unit表示要转换成的单位,value表示数值,metrics表示当前的度量方式 // DIAMETER是常量0x1E,十进制为30,下面语句就表示tmp的值为30dp换算成的像素数值 float tmp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRadius, metrics); // ceil函数表示向上取整 mDiameter = (int) Math.ceil(tmp); tmp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mTrokeWidth, metrics); mWidth = (int) Math.ceil(tmp); Paint p = new Paint(); p.setStyle(Paint.Style.STROKE); p.setAntiAlias(true); // setStrokeWidth()设置画笔宽度 // p.setStrokeWidth(0.5F*mWidth+0.5F*mDiameter); p.setStrokeWidth(0.4F * mWidth); p.setStrokeCap(Paint.Cap.SQUARE);//直角进度条 p.setColor(defaultColor); mPaint = p; float rightTop = (float) (mWidth / 2.0);// 这个值就是圆环宽度(大圆半径-小圆半径) mRect = new RectF(rightTop, rightTop, mDiameter + rightTop, mDiameter + rightTop); mProgress = 0; } protected boolean clear = false; @Override protected void onDraw(Canvas canvas) { // super.onDraw(canvas); // 如果mProgress<360,则圆形进度条还未旋转完成,则用0x7f的透明度绘制一个完整的圆形作为进度条背景 // 注意要先绘制背景条,再绘制进度条,因为后绘制的会覆盖在先绘制的上面 /* * if (mProgress < 360) { paint.setAlpha(0x7f); * paint.setColor(defaultColor); canvas.drawArc(mRect, 135, 270, false, * paint); } */ if (clear) { mPaint.setColor(Color.TRANSPARENT); clear = false; return; } if (mProgress != 0) { Paint paint = mPaint; paint.setColor(mArcColor); float degree = 360.0f * mProgress / 360; paint.setAlpha(0xff); paint.setColor(mArcColor); canvas.drawArc(mRect, mStartAngle, degree, false, paint); } } @Override protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // mDiameter表示小圆直径,mWidth表示圆环宽度的2倍,所以meas表示大圆直径 // 所以View的hight,width都为meas final int meas = mDiameter + mWidth; setMeasuredDimension(meas, meas); } public void setProgress(int p) { mProgress = p; invalidate(); } public void postProgress(final int p) { post(new Runnable() { @Override public void run() { setProgress(p); } }); } public void setmArcColor(int mArcColor) { this.mArcColor = mArcColor; } public void reset() { clear = true; invalidate(); mProgress = 0; } public void setGrade(final RoundProgressBar arcProgressbar, final TextView tv_grade, final int g) { mProgress = 1; arcProgressbar.reset(); final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // if (0 < (mProgress / 3.6) && (mProgress / 3.6) <= 59) { // arcProgressbar.setmArcColor(Color.parseColor("#ff0000")); // tv_grade.setTextColor(Color.parseColor("#ff0000")); // } else if (60 < (mProgress / 3.6) && (mProgress / 3.6) <= 79) { // arcProgressbar.setmArcColor(Color.parseColor("#f39700")); // tv_grade.setTextColor(Color.parseColor("#f39700")); // } else if (80 < (mProgress / 3.6) && (mProgress / 3.6) <= 100) { // arcProgressbar.setmArcColor(Color.parseColor("#42ae7c")); // tv_grade.setTextColor(Color.parseColor("#42ae7c")); // } arcProgressbar.setmArcColor(Color.parseColor("#ffffff")); tv_grade.setTextColor(Color.parseColor("#000000")); if (msg.what == 0x1223) { arcProgressbar.setProgress(mProgress * (1)); tv_grade.setText((int) (mProgress / 3.6)+"%"); } else if (msg.what == 0x1224) { tv_grade.setText(g+"%"); } } }; new Timer().schedule(new TimerTask() { @Override public void run() { Message msg = new Message(); if (mProgress < (int) (((float) 360 / 100) * g)) { msg.what = 0x1223; mProgress++; } else { msg.what = 0x1224; this.cancel(); } handler.sendMessage(msg); } }, 0, 5); } }
里面的一些设置:
<!--首页顶部进度条格式--> <declare-styleable name="ArcProgressbar"> <!-- 圆环起始角度--> <attr name="startAngle" format="integer" /> <!-- 圆环的宽度 默认115--> <attr name="trokeWidth" format="integer" /> <!-- 进度条进度颜色 --> <attr name="arcColor" format="color" /> </declare-styleable>
颜色,可以通过设置drawble文件中设置xml的方式来进行。
背景色
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@color/blue_grey"></solid> </shape>
样式
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="ring" android:useLevel="false"> <stroke android:width= "16px" android:color= "@color/dark_blue" /> </shape>
进度条颜色
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="@color/light_white"></solid> </shape>
样式:
布局:
<!--圆形进度条动画--> <RelativeLayout android:layout_width="350px" android:layout_height="350px" android:layout_marginTop="50px"> <ImageView android:layout_width="310px" android:layout_height="310px" android:background="@drawable/blue_grey_round_shape" android:layout_centerInParent="true"/> <qnkj.cn.lianxiapp.RoundProgressBar android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/roundProgress" android:layout_centerInParent="true"/> <ImageView android:layout_width="138px" android:layout_height="138px" android:background="@drawable/dark_blue_ring" android:layout_centerInParent="true"></ImageView> <TextView android:layout_width="104px" android:layout_height="104px" android:id="@+id/tv_value" android:layout_centerInParent="true" android:gravity="center" android:text="0%" android:textSize="@dimen/thirty_two" android:background="@drawable/white_round"/> </RelativeLayout>
使用:
//圆形进度条 TextView tvValue=findViewById(R.id.tv_value); RoundProgressBar RoundProgressBar= findViewById(R.id.roundProgress); RoundProgressBar.setProgress(56); //自定义view,内部显示文字的view,数字是进度 RoundProgressBar.setGrade(RoundProgressBar, tvValue, 56);布局有些乱,凑活着看吧。是在不行,复制粘贴下来代码也能用(没问题的话)