自定义view之动态圆形进度条

来源:互联网 发布:教育视频网站知乎 编辑:程序博客网 时间:2024/04/29 01:17

很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如onDraw,为了我们自定义的View在一个项目中能够重用,有时候我们需要自定义其属性,举个很简单的例子,我在项目中的多个界面使用我自定义的View,每个界面该自定义View的颜色都不相同,这时候如果没有自定义属性,那我们是不是需要构建不同颜色的View出来呢,这样子我们的代码就会显得很沉厄,所以这时候我们就需要自定义其属性来满足我们不同的需求,自定义属性呢,我们需要在values下建立attrs.xml文件,在其中定义我们需要定义的属性,然后在自定义View中也要做相对应的修改,我们还是用一个小例子来看看自定义View和自定义属性的使用


今天带大家来自己定义一个带进度的圆形进度条,我们还是先看一下效果吧





1.在values下面新建一个attrs.xml,现在里面定义我们的属性,不同的属性对应不同的format,属性对应的format可以参考http://blog.csdn.net/pgalxx/article/details/6766677,介绍的还是比较详细,接下来我贴上我在自定义这个进度条所用到的属性

  1. <?xml version="1.0" encoding="UTF-8"?><resources>        <!--自定义实现写字板-->    <declare-styleable name="CustomPaint">        <attr name="boardBackground" format="color"></attr> <!--写字板背景颜色-->        <attr name="paintColor" format="color"></attr><!--画笔颜色-->        <attr name="paintWidth" format="dimension"></attr><!--画笔宽度-->    </declare-styleable>    <!--自定义进度条-->    <declare-styleable name="CustomProgress">        <attr name="radius" format="dimension" /><!--半径-->        <attr name="strokeWidth" format="dimension" /><!--画笔宽度-->        <attr name="circleColor" format="color" /><!--内圆颜色-->        <attr name="ringColor" format="color" /><!--进度条颜色-->        <attr name="totalProgress" format="integer" /><!--总进度-->        <attr name="textColor" format="color|reference" /><!--字体颜色-->        <attr name="bigCircleColor" format="color" /><!--外圆颜色-->    </declare-styleable></resources>

           2.自定义paint的全部代码贴出来,里面的代码我也有详细的注释 
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;/** * @类的用途: * @author: 李晓倩 * @date: 2017/6/11 */public class CustomPaint extends View {    private int mBoardBackground;//写字板背景颜色    private int mPaintColor;//画笔颜色    private int mPaintWidth;//画笔宽度    private Paint mPaint;    private Path mPath;    public CustomPaint(Context context) {        this(context, null);    }    public CustomPaint(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CustomPaint(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context, attrs);    }    private void init(Context context, AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomPaint);        mBoardBackground = typedArray.getColor(R.styleable.CustomPaint_boardBackground, Color.WHITE);        mPaintColor = typedArray.getColor(R.styleable.CustomPaint_paintColor, Color.BLACK);        mPaintWidth = typedArray.getDimensionPixelSize(R.styleable.CustomPaint_paintWidth, 15);        typedArray.recycle();        mPaint = new Paint();        mPath = new Path();        setBackgroundColor(mBoardBackground);        mPaint.setColor(mPaintColor);        mPaint.setStrokeWidth(mPaintWidth);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setAntiAlias(true);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawPath(mPath, mPaint);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        float touchX = event.getX();        float touchY = event.getY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mPath.moveTo(touchX, touchY);                break;            case MotionEvent.ACTION_MOVE:                mPath.lineTo(touchX, touchY);                break;            case MotionEvent.ACTION_UP:                break;        }        invalidate();        return true;    }}

 3.自定义View的全部代码贴出来,里面的代码我也有详细的注释 
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;/** * @类的用途: * @author: 李晓倩 * @date: 2017/6/11 */public class CustomProgress extends View {    // 画实心圆的画笔    private Paint mCirclePaint;    // 画圆环的画笔    private Paint mRingPaint;    // 画字体的画笔    private Paint mTextPaint;    // 圆形颜色    private int mCircleColor;    // 圆环颜色    private int mRingColor;    // 半径    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;    // 当前进度    private int mProgress;    //大圆    private Paint mBigPatient;    //字体颜色    private int mTextColor;    //外圆颜色    private int mBigCircleColor;    public CustomProgress(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.CustomProgress, 0, 0);        mRadius = typeArray.getDimension(R.styleable.CustomProgress_radius, 300);        mStrokeWidth = typeArray.getDimension(R.styleable.CustomProgress_strokeWidth, 20);        mCircleColor = typeArray.getColor(R.styleable.CustomProgress_circleColor, Color.BLUE);        mRingColor = typeArray.getColor(R.styleable.CustomProgress_ringColor, Color.RED);        mTotalProgress = typeArray.getInt(R.styleable.CustomProgress_totalProgress, 100);        mTextColor = typeArray.getColor(R.styleable.CustomProgress_textColor, Color.WHITE);        mBigCircleColor = typeArray.getColor(R.styleable.CustomProgress_bigCircleColor, Color.WHITE);        typeArray.recycle();//注意这里要释放掉        mRingRadius = mRadius + mStrokeWidth / 2;    }    private void initVariable() {        mCirclePaint = new Paint();        mCirclePaint.setAntiAlias(true);        mCirclePaint.setColor(mCircleColor);        mCirclePaint.setStrokeCap(Paint.Cap.ROUND);        mCirclePaint.setStyle(Paint.Style.FILL);        mRingPaint = new Paint();        mRingPaint.setAntiAlias(true);        mRingPaint.setColor(mRingColor);        mRingPaint.setStrokeCap(Paint.Cap.ROUND);        mRingPaint.setStyle(Paint.Style.STROKE);        mRingPaint.setStrokeWidth(mStrokeWidth);        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);        mTextPaint.setStyle(Paint.Style.FILL);        mTextPaint.setColor(mTextColor);        mTextPaint.setTextSize(mRadius / 2);        mBigPatient = new Paint();        mBigPatient.setColor(mBigCircleColor);        mBigPatient.setAntiAlias(true);        mBigPatient.setStyle(Paint.Style.FILL);        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 + mStrokeWidth, mBigPatient);        canvas.drawCircle(mXCenter, mYCenter, mRadius, mCirclePaint);        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 = (int) (mProgress * 1.0f / mTotalProgress * 100) + "%";            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();    }    public void setmTotalProgress(int totalProgress) {        mTotalProgress = totalProgress;    }}
4.布局文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              xmlns:app="http://schemas.android.com/apk/res-auto"              xmlns:tools="http://schemas.android.com/tools"              android:layout_width="match_parent"              android:layout_height="match_parent"              android:gravity="center"              android:orientation="vertical"              tools:context=".MainActivity"             >    <test.bwie.com.autoviewdemo.CustomProgress        android:id="@+id/custom_progress"        android:layout_width="100dp"        android:layout_height="100dp"        app:bigCircleColor="#3de822"        app:circleColor="#ffffff"        app:radius="30dp"        app:strokeWidth="10dp"        app:textColor="#000" /></LinearLayout>
 

5.使用到自定义view的activity,这里使用的MainActivity

import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {    private CustomProgress customProgress;    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            if (msg.what == 1) {                customProgress.setProgress(msg.arg1);            }            super.handleMessage(msg);        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        customProgress = (CustomProgress) findViewById(R.id.custom_progress);        customProgress.setmTotalProgress(100);        new Thread(new Runnable() {            @Override            public void run() {                try {                    for (int i = 1; i <= 100; i++) {                        Thread.sleep(1000);                        Message message = handler.obtainMessage();                        message.what = 1;                        message.arg1 = i;                        handler.sendMessage(message);                    }                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }).start();    }}

原创粉丝点击