Android - 自定义 View - 弧线展示图

2021-09-24 12:03:46 浏览数 (1)

 Android 群英传 学习笔记


1.首先是我们需要的成员变量

代码语言:javascript复制
    /*
    数据成员
     */
    private float mCircleXY   = 0 ;
    private float mRadius     = 0 ;
    private float length      = 0 ;
    private float mSweepValue = 0;

    /*
    Paint
     */
    private Paint mCirclePaint;
    private Paint mArcPaint;
    private Paint mTextPaint;
    private Paint mPaint;

    /*
    RectF
     */
    private RectF mRectF;

    /*
    Text
     */
    private String mShowText;

2.然后我们需要配置四种画笔

代码语言:javascript复制
    /*
    配置绘笔
     */
    private void iniView(){
        /*
        Paint
          */
        mCirclePaint = new Paint();//中心圆
        mCirclePaint.setColor(Color.RED);
        mCirclePaint.setAntiAlias(true);

        mTextPaint = new Paint();//中心文字
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(30);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setStrokeWidth(0);

        mArcPaint = new Paint();//外围圆( 未填充的轨道部分 )
        mArcPaint.setStrokeWidth(100);
        mArcPaint.setAntiAlias(true);
        mArcPaint.setColor(Color.GREEN);
        mArcPaint.setStyle(Paint.Style.STROKE);

        mPaint = new Paint();//外围圆( 填充后 )
        mPaint.setStrokeWidth(100);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);

        /*
        Text
        */
        mShowText = "0%";
    }

3.重写 onDraw() 方法进行绘制:

代码语言:javascript复制
    /*
    绘图
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /*
        RectF
        必须写在 onDraw 里
         */
        mRectF = new RectF(
                (float)(length*0.1),
                (float)(length*0.1),
                (float)(length*0.9),
                (float)(length*0.9)
        );
        // 绘制圆
        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
        // 绘制弧线
        canvas.drawArc(mRectF, 200, 360, false, mPaint);//外围圆形轨道
        canvas.drawArc(mRectF, 200, mSweepValue, false, mArcPaint);//占满部分 0 ~ 360 圆心角换算
        // 绘制文字
        float textWidth = mTextPaint.measureText(mShowText);// 测量字体宽度,我们需要根据宽度设置文字居中
        canvas.drawText(mShowText, (int)(length/2 - textWidth/2), (int)(length/2   textWidth/2), mTextPaint);

    }

4.添加方法:用户调用来设置进度百分比:

代码语言:javascript复制
    public void setProgress(float mSweepValue) {
        float a = (float) mSweepValue;
        if (a != 0) {
            this.mSweepValue = (float) (360.0 * (a / 100.0));
            mShowText = mSweepValue   "%";
            Log.e("this.mSweepValue:", this.mSweepValue   "");
        } else {
            this.mSweepValue = 25;
            mShowText = 25   "%";
        }

        invalidate();
    }

全部代码:

. View 的实现部分:

代码语言:javascript复制
public class UI3_6_3_1 extends View {

    /*
    数据成员
     */
    private float mCircleXY   = 0 ;
    private float mRadius     = 0 ;
    private float length      = 0 ;
    private float mSweepValue = 0;

    /*
    Paint
     */
    private Paint mCirclePaint;
    private Paint mArcPaint;
    private Paint mTextPaint;
    private Paint mPaint;

    /*
    RectF
     */
    private RectF mRectF;

    /*
    Text
     */
    private String mShowText;

    /*
    构造方法
     */
    public UI3_6_3_1(Context context) {
        super(context);
        iniView();
    }

    public UI3_6_3_1(Context context, AttributeSet attrs) {
        super(context, attrs);
        iniView();
    }

    public UI3_6_3_1(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        iniView();
    }

    /*
    配置绘笔
     */
    private void iniView(){
        /*
        Paint
          */
        mCirclePaint = new Paint();//中心圆
        mCirclePaint.setColor(Color.RED);
        mCirclePaint.setAntiAlias(true);

        mTextPaint = new Paint();//中心文字
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(30);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setStrokeWidth(0);

        mArcPaint = new Paint();//外围圆( 未填充的轨道部分 )
        mArcPaint.setStrokeWidth(100);
        mArcPaint.setAntiAlias(true);
        mArcPaint.setColor(Color.GREEN);
        mArcPaint.setStyle(Paint.Style.STROKE);

        mPaint = new Paint();//外围圆( 填充后 )
        mPaint.setStrokeWidth(100);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);

        /*
        Text
        */
        mShowText = "0%";
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
//        Point p = new Point();
//        //获取窗口管理器
//        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//        wm.getDefaultDisplay().getSize(p);
        length = w; // 屏幕宽度
        mCircleXY = length/2;
        mRadius   = (float)(length*0.5/2);
    }

    /*
    绘图
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /*
        RectF
        必须写在 onDraw 里
         */
        mRectF = new RectF(
                (float)(length*0.1),
                (float)(length*0.1),
                (float)(length*0.9),
                (float)(length*0.9)
        );
        // 绘制圆
        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
        // 绘制弧线
        canvas.drawArc(mRectF, 200, 360, false, mPaint);//外围圆形轨道
        canvas.drawArc(mRectF, 200, mSweepValue, false, mArcPaint);//占满部分 0 ~ 360 圆心角换算
        // 绘制文字
        float textWidth = mTextPaint.measureText(mShowText);// 测量字体宽度,我们需要根据宽度设置文字居中
        canvas.drawText(mShowText, (int)(length/2 - textWidth/2), (int)(length/2   textWidth/2), mTextPaint);

    }


    public void setProgress(float mSweepValue) {
        float a = (float) mSweepValue;
        if (a != 0) {
            this.mSweepValue = (float) (360.0 * (a / 100.0));
            mShowText = mSweepValue   "%";
            Log.e("this.mSweepValue:", this.mSweepValue   "");
        } else {
            this.mSweepValue = 25;
            mShowText = 25   "%";
        }

        invalidate();
    }

}

. XML 文件

代码语言:javascript复制

. 活动中调用

代码语言:javascript复制
public class MainActivity extends BaseActivity {

    //创建自定义控件
    private TopBar topBar;
    private UI3_6_3_1 ui3_6_3_1;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ui3_6_3_1.setProgress(msg.arg1);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ui3_6_3_1 = (UI3_6_3_1) findViewById(R.id.ui_3_6_3_1);
        new Thread(){
            @Override
            public void run() {
                int i = 0 ;
                while (i   < 100){
                    try {
                        sleep(100);
                        Message msg = new Message();
                        msg.arg1 = i;
                        handler.sendMessage(msg);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d("123123", "123123");
                }
            }
        }.start();
    }
}

0 人点赞