Android绘图:自定义View之——矩形进度条、圆环进度条、填充型进度条、时钟

来源:互联网 发布:女朋友突然说分手 知乎 编辑:程序博客网 时间:2024/05/22 02:09

      • 主函数
        • 矩形进度条自定义View
        • 矩形进度条的布局
        • 成像图
        • 圆环形进度条自定义View
        • 圆环形进度条的布局
        • 成像图
        • 填充型进度条自定义View
        • 填充型进度条布局
        • 成像图
        • 时钟自定义View
        • 时钟自定义View布局
        • 成像图

主函数

这几种进度条的主函数都是类似的,所以下面我只给出了一个填充型进度条的主函数,其他几个主函数只是在这基础上改动一下按钮id(即与各自布局里面的id相同即可),还有改动一下相对应的类即可。

public class MainActivity extends AppCompatActivity {    private Button mButtonStart;    private MyProgress myProgress;    private int progress;    private static final int PROGRESS=0X23;    private Handler handler=new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what){                case PROGRESS:                    progress++;                    if (progress<=100){                        myProgress.setCurrentProgress(progress);                        handler.sendEmptyMessageDelayed(PROGRESS,200);                    }                    break;            }        }    };   @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mButtonStart= (Button) findViewById(R.id.button_start);        myProgress= (MyProgress) findViewById(R.id.myprogress);        mButtonStart.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                handler.sendEmptyMessageDelayed(PROGRESS,1000);            }        });        }   } 

矩形进度条自定义View

public class Rectangle extends View {    private int mProgress;    private Paint mCurrentProgress;    private Paint mMaxProgress;    private Paint mPaintText;    private int mWidth;    private int mHeight;    public Rectangle(Context context) {        super(context);    }    public Rectangle(Context context, AttributeSet attrs) {        super(context, attrs);        mCurrentProgress = new Paint();        mCurrentProgress.setColor(Color.YELLOW);        mCurrentProgress.setAntiAlias(true);        mMaxProgress = new Paint();        mMaxProgress.setColor(Color.WHITE);        mMaxProgress.setAntiAlias(true);        mPaintText = new Paint();        mPaintText.setColor(Color.RED);        mPaintText.setStrokeWidth(5);        mPaintText.setAntiAlias(true);        mPaintText.setTextSize(100);        mPaintText.setTextAlign(Paint.Align.CENTER);    }        public int getmProgress() {            return mProgress;        }        public void setmProgress(int mProgress) {            this.mProgress = mProgress;            invalidate();        }        @Override        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {            super.onMeasure(widthMeasureSpec, heightMeasureSpec);            mWidth=getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);            mHeight= getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        }        @Override        protected void onDraw(Canvas canvas) {            super.onDraw(canvas);            canvas.drawRect(mWidth / 2-160, mHeight / 2-250,mWidth / 2+160, mHeight / 2+250, mMaxProgress);            canvas.drawRect(mWidth / 2-160, mHeight / 2+250-(mProgress/100f*500),mWidth / 2+160, mHeight / 2+250, mCurrentProgress);            canvas.drawText(mProgress+"%", mWidth / 2, mHeight / 2,  mPaintText);        }    }

矩形进度条的布局

<Button        android:id="@+id/button_round"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="开始下载"/>   <com.example.administrator.definedviewdemo.Wiget.Rectangle        android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/rectangle"/>      

成像图

这里写图片描述

圆环形进度条自定义View

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;/** * Created by Administrator on 2015/9/16. */public class RoundProgressBar extends View {    private Paint mPaintBackCircle;    private Paint mPaintInfrontCircle;    private int currentProgress;    private int mwidth;    private int mheight;    private Paint mPaintText;    private RectF mOval;    public int getCurrentProgress() {        return currentProgress;    }    public void setCurrentProgress(int currentProgress) {        this.currentProgress = currentProgress;        invalidate();//告诉UI线程重新绘制    }    public RoundProgressBar(Context context) {        super(context);    }    public RoundProgressBar(Context context, AttributeSet attrs) {        super(context, attrs);        mPaintBackCircle=new Paint();        mPaintBackCircle.setColor(Color.GRAY);        mPaintBackCircle.setStrokeWidth(1);        mPaintBackCircle.setAntiAlias(true);        mPaintBackCircle.setStyle(Paint.Style.STROKE);        mPaintInfrontCircle=new Paint();        mPaintInfrontCircle.setColor(Color.GREEN);        //这里的宽度是画填充圆环时的宽度,即两个圆的半径之差。        mPaintInfrontCircle.setStrokeWidth(40);        mPaintInfrontCircle.setAntiAlias(true);        mPaintInfrontCircle.setStyle(Paint.Style.STROKE);        mPaintText=new Paint();        mPaintText.setColor(Color.RED);        mPaintText.setTextSize(50);        mPaintText.setTextAlign(Paint.Align.CENTER);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mwidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        mheight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawCircle(mwidth/2, mheight/2,200,mPaintBackCircle);        canvas.drawCircle(mwidth/2, mheight/2,160,mPaintBackCircle);         // 设置个新的长方形,扫描测量,减去的值为两个半径的中间值        RectF oval1=new RectF(mwidth / 2-180, mheight / 2-180,mwidth / 2+180, mheight / 2+180);        // 画弧,第一个参数是RectF:该类是第二个参数是角度的开始,第三个参数是多少度,第四个参数是真的时候画扇形,是假的时候画弧线        canvas.drawArc( oval1, 0,currentProgress/100f*360 ,false, mPaintInfrontCircle);        canvas.drawText(currentProgress+"%",mwidth/2,mheight/2,mPaintText);    }}

圆环形进度条的布局

 <Button        android:id="@+id/button_round"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="开始下载"/>    <com.example.administrator.definedviewdemo.Wiget.RoundProgressBar        android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/round"/>

成像图

这里写图片描述

填充型进度条自定义View

public class MyProgress extends View {    private int mWidth;    private int mHeight;    private Paint mPaintBackGround;    private Paint mPaintCurrent;    private Paint mPaintText;    private int  currentProgress;    public int getCurrentProgress() {        return currentProgress;    }    public void setCurrentProgress(int currentProgress) {        this.currentProgress = currentProgress;        invalidate();//告诉UI线程重新绘制    }    public MyProgress(Context context) {        super(context);    }    public MyProgress(Context context, AttributeSet attrs) {        super(context, attrs);        mPaintBackGround = new Paint();        mPaintBackGround.setAntiAlias(true);        mPaintBackGround.setColor(Color.GRAY);        mPaintCurrent = new Paint();        mPaintCurrent.setAntiAlias(true);        mPaintCurrent.setColor(Color.GREEN);        mPaintText = new Paint();        mPaintText.setAntiAlias(true);        mPaintText.setColor(Color.BLACK);        mPaintText.setTextSize(100);        mPaintText.setTextAlign(Paint.Align.CENTER);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawCircle(mWidth / 2, mHeight / 2, 200, mPaintBackGround);        canvas.drawCircle(mWidth / 2, mHeight / 2, 200/100f*currentProgress,mPaintCurrent);        canvas.drawText(currentProgress+"%", mWidth / 2, mHeight / 2, mPaintText);    }}

填充型进度条布局

<Button        android:id="@+id/button_start"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="开始下载"/>    <com.example.administrator.definedviewdemo.Wiget.MyProgress        android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/myprogress"/>

成像图

这里写图片描述

时钟自定义View

public class MyView extends View {    private int mWidth;    private int mHeight;    private Paint mPaint;    private Paint mPaintMinute;    private Paint mPaintHour;    private Paint mPaintCircle;    private Paint mPaintText;    private Calendar mCalendar;    private static final int NEED_UPDATE=34;    private Handler mHandler=new Handler(){        public void handleMessage(Message msg) {            switch (msg.what) {                case NEED_UPDATE:                    mCalendar=Calendar.getInstance();                    invalidate();                    mHandler.sendEmptyMessageDelayed(NEED_UPDATE, 1000);                    break;                default:                    break;            }        };    };    public MyView(Context context) {        super(context);    }    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);        mCalendar=Calendar.getInstance();        //查看api以了解它的具体使用方法(canvas View的api)        mPaint = new Paint();        mPaint.setColor(Color.RED);        mPaint.setStrokeWidth(5);        mPaint.setAntiAlias(true);        mPaintHour = new Paint();        mPaintHour.setColor(Color.BLACK);        mPaintHour.setStrokeWidth(5);        mPaintHour.setAntiAlias(true);        mPaintMinute = new Paint();        mPaintMinute.setColor(Color.GREEN);        mPaintMinute.setStrokeWidth(5);        mPaintMinute.setAntiAlias(true);        mPaintCircle = new Paint();        mPaintCircle.setColor(Color.BLUE);        mPaintCircle.setStrokeWidth(5);        mPaintCircle.setAntiAlias(true);        mPaintCircle.setStyle(Paint.Style.STROKE);        mPaintText = new Paint();        mPaintText.setColor(Color.DKGRAY);        mPaintText.setTextSize(30);        mPaintText.setTextAlign(Paint.Align.CENTER);        mPaintText.setStrokeWidth(5);        mPaintText.setAntiAlias(true);        mHandler.sendEmptyMessageDelayed(NEED_UPDATE, 1000);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));    }    @Override    protected void onDraw(Canvas canvas) {        {            super.onDraw(canvas);            // 传入像素值,查看api            //画出表盘            canvas.drawCircle(mWidth / 2, mHeight / 2, 300, mPaintCircle);            canvas.drawCircle(mWidth / 2, mHeight / 2, 10, mPaintCircle);            for (int i = 1; i <= 12; i++) {                //保存画布此时的状态                canvas.save();                canvas.rotate(360 / 12 * i, mWidth / 2, mHeight / 2);                canvas.drawLine(mWidth / 2, mHeight / 2 - 300, mWidth / 2 - 1, mHeight / 2 - 280, mPaint);                canvas.drawText("" + i, mWidth / 2, mHeight / 2 - 240, mPaintText);                //配合save()使用                canvas.restore();            }            //画出时钟的分针            int minute=mCalendar.get(Calendar.MINUTE);            int hour=mCalendar.get(Calendar.HOUR);            float degreeMinute=minute/60f*360;            canvas.save();            canvas.rotate(degreeMinute,mWidth / 2, mHeight / 2);            canvas.drawLine(mWidth / 2, mHeight / 2-200, mWidth / 2, mHeight / 2+18, mPaintMinute);            canvas.restore();            //画出时钟的时针,计算时针的位置,因为时针一天走两圈,所以除以720,在乘以角度360            float degreeHour=(hour*60+minute)/12f/60*360;            canvas.save();            canvas.rotate(degreeHour,mWidth / 2, mHeight / 2);            canvas.drawLine(mWidth / 2, mHeight / 2-150, mWidth / 2, mHeight / 2+14, mPaintHour);            canvas.restore();        }        //画出秒针        int seconde=mCalendar.get(Calendar.SECOND);        float degreeSeconde=seconde*6;        canvas.save();        canvas.rotate(degreeSeconde,mWidth / 2, mHeight / 2);        canvas.drawLine(mWidth / 2, mHeight / 2-250, mWidth / 2, mHeight / 2+24, mPaint);        canvas.restore();    }}

特别注意:

//画线的时候,起始点的高度和终止点的高度千万不能写错了——即起始点的高度小于终止点的高度,而且起始点离内圆圆心的长度大于终止点到内圆的长度。
canvas.drawLine(mwidth / 2, mheight / 2 -100, mwidth / 2, mheight / 2 +25, mPaintLine);

时钟自定义View布局

<com.example.administrator.definedviewdemo.Wiget.MyView    android:layout_width="match_parent"    android:layout_height="match_parent" />

成像图

这里写图片描述

0 0
原创粉丝点击