Android 自定义漂亮的圆形进度条

来源:互联网 发布:java方法泛型 t.class 编辑:程序博客网 时间:2024/06/06 22:04

公司有这样一个需求,实现这个圆弧进度条

所以,现在就将它抽取出来分享

  • 如果需要是圆帽的就将,下面这句代码放开即可
    • mRingPaint.setStrokeCap(Paint.Cap.ROUND);//设置线冒样式,有圆 有方

这里写图片描述


不废话,直接上代码


  • 自定义view
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;/** * Created by Administrator on 2017/8/5. */public class CompletedView extends View {    // 画实心圆的画笔    private Paint mCirclePaint;    // 画圆环的画笔    private Paint mRingPaint;    // 画圆环的画笔背景色    private Paint mRingPaintBg;    // 画字体的画笔    private Paint mTextPaint;    // 圆形颜色    private int mCircleColor;    // 圆环颜色    private int mRingColor;    // 圆环背景颜色    private int mRingBgColor;    // 半径    private float mRadius;    // 圆环半径    private float mRingRadius;    // 圆环宽度    private float mStrokeWidth;    // 圆心x坐标    private int mXCenter;    // 圆心y坐标    private int mYCenter;    // 字的长度    private float mTxtWidth;    // 字的高度    private float mTxtHeight;    // 总进度    private int mTotalProgress = 100;    // 当前进度    private int mProgress;    public CompletedView(Context context, AttributeSet attrs) {        super(context, attrs);        // 获取自定义的属性        initAttrs(context, attrs);        initVariable();    }    //属性    private void initAttrs(Context context, AttributeSet attrs) {        TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs,                R.styleable.TasksCompletedView, 0, 0);        mRadius = typeArray.getDimension(R.styleable.TasksCompletedView_radius, 80);        mStrokeWidth = typeArray.getDimension(R.styleable.TasksCompletedView_strokeWidth, 10);        mCircleColor = typeArray.getColor(R.styleable.TasksCompletedView_circleColor, 0xFFFFFFFF);        mRingColor = typeArray.getColor(R.styleable.TasksCompletedView_ringColor, 0xFFFFFFFF);        mRingBgColor = typeArray.getColor(R.styleable.TasksCompletedView_ringBgColor, 0xFFFFFFFF);        mRingRadius = mRadius + mStrokeWidth / 2;    }    //初始化画笔    private void initVariable() {        //内圆        mCirclePaint = new Paint();        mCirclePaint.setAntiAlias(true);        mCirclePaint.setColor(mCircleColor);        mCirclePaint.setStyle(Paint.Style.FILL);        //外圆弧背景        mRingPaintBg = new Paint();        mRingPaintBg.setAntiAlias(true);        mRingPaintBg.setColor(mRingBgColor);        mRingPaintBg.setStyle(Paint.Style.STROKE);        mRingPaintBg.setStrokeWidth(mStrokeWidth);        //外圆弧        mRingPaint = new Paint();        mRingPaint.setAntiAlias(true);        mRingPaint.setColor(mRingColor);        mRingPaint.setStyle(Paint.Style.STROKE);        mRingPaint.setStrokeWidth(mStrokeWidth);        //mRingPaint.setStrokeCap(Paint.Cap.ROUND);//设置线冒样式,有圆 有方        //中间字        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);        mTextPaint.setStyle(Paint.Style.FILL);        mTextPaint.setColor(mRingColor);        mTextPaint.setTextSize(mRadius / 2);        Paint.FontMetrics fm = mTextPaint.getFontMetrics();        mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);    }    //画图    @Override    protected void onDraw(Canvas canvas) {        mXCenter = getWidth() / 2;        mYCenter = getHeight() / 2;        //内圆        canvas.drawCircle(mXCenter, mYCenter, mRadius, mCirclePaint);        //外圆弧背景        RectF oval1 = new RectF();        oval1.left = (mXCenter - mRingRadius);        oval1.top = (mYCenter - mRingRadius);        oval1.right = mRingRadius * 2 + (mXCenter - mRingRadius);        oval1.bottom = mRingRadius * 2 + (mYCenter - mRingRadius);        canvas.drawArc(oval1, 0, 360, false, mRingPaintBg); //圆弧所在的椭圆对象、圆弧的起始角度、圆弧的角度、是否显示半径连线        //外圆弧        if (mProgress > 0 ) {            RectF oval = new RectF();            oval.left = (mXCenter - mRingRadius);            oval.top = (mYCenter - mRingRadius);            oval.right = mRingRadius * 2 + (mXCenter - mRingRadius);            oval.bottom = mRingRadius * 2 + (mYCenter - mRingRadius);            canvas.drawArc(oval, -90, ((float)mProgress / mTotalProgress) * 360, false, mRingPaint); //            //字体            String txt = mProgress + "分";            mTxtWidth = mTextPaint.measureText(txt, 0, txt.length());            canvas.drawText(txt, mXCenter - mTxtWidth / 2, mYCenter + mTxtHeight / 4, mTextPaint);        }    }    //设置进度    public void setProgress(int progress) {        mProgress = progress;        postInvalidate();//重绘    }}

  • attrs.xml文件
<?xml version="1.0" encoding="utf-8"?><resources>    <!--圆弧进度条-->    <declare-styleable name="TasksCompletedView">        <attr name="radius" format="dimension"/>        <attr name="strokeWidth" format="dimension"/>        <attr name="circleColor" format="color"/>        <attr name="ringColor" format="color"/>        <attr name="ringBgColor" format="color"/>    </declare-styleable></resources>

  • color.xml文件
<?xml version="1.0" encoding="utf-8"?><resources>    <color name="colorPrimary">#3F51B5</color>    <color name="colorPrimaryDark">#303F9F</color>    <color name="colorAccent">#FF4081</color>    <color name="white">#FFFFFF</color>    <color name="white2">#f5f3f3</color>    <color name="colorRed">#d50f09</color></resources>
  • MainActivity文件!,,,注意,,,开一个子线程去刷新进度,如果用系统handler去更新,阻塞主线程会出现界面刷新的卡顿情况,因为handler就是程操作主线程的
public class MainActivity extends AppCompatActivity {    private int mTotalProgress = 90;    private int mCurrentProgress = 0;    //进度条    private CompletedView mTasksView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mTasksView = (CompletedView) findViewById(R.id.tasks_view);        new Thread(new ProgressRunable()).start();    }    class ProgressRunable implements Runnable {        @Override        public void run() {                while (mCurrentProgress < mTotalProgress) {                    mCurrentProgress += 1;                    mTasksView.setProgress(mCurrentProgress);                    try {                        Thread.sleep(90);                    } catch (Exception e) {                        e.printStackTrace();                    }                }        }    }}
  • activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tc="http://schemas.android.com/apk/res/com.example.administrator.arcprogresbar"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#addafd"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:orientation="vertical">        <com.example.administrator.arcprogresbar.CompletedView            android:id="@+id/tasks_view"            android:layout_width="223dp"            android:layout_height="223dp"            tc:circleColor="@color/white"            tc:radius="50dip"            tc:ringBgColor="@color/white2"            tc:ringColor="@color/colorRed"            tc:strokeWidth="10dip" />    </LinearLayout></LinearLayout>

布局文件中后面自定义命名空间接着的是应用的包名:xmlns:tc=”http://schemas.android.com/apk/res/com.example.administrator.arcprogresbar”

  • 注意:xmlns:tc=”http://schemas.android.com/apk/res/包名”

  • 再次提醒:刷新进度条要用子线程去执行,防止主线程出现卡顿情况

  • 源码下载:http://download.csdn.net/detail/qq_32519693/9922309

原创粉丝点击