zoukankan      html  css  js  c++  java
  • Android 自定义漂亮的圆形进度条

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

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

    • 如果需要是圆帽的就将,下面这句代码放开即可 
      • 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”

  • 相关阅读:
    WPF快速指导10:WPF中的事件及冒泡事件和隧道事件(预览事件)的区别
    改善C#程序的建议1:非用ICloneable不可的理由
    WPF快速指导5:验证
    改善C#程序的建议4:C#中标准Dispose模式的实现
    我所入选的微软技术社区电子报
    C#中new, override, virtual的具体用法
    C#中FCL迭代器模式的一点问题
    WPF快速指导3:数据绑定
    WPF快速指导2:模板
    C#高效编程话题集2(每期10话题)
  • 原文地址:https://www.cnblogs.com/xgjblog/p/8707182.html
Copyright © 2011-2022 走看看