获取attrs.xml中声明的自定义属性的值

时间:2021-03-05 20:40:40

关键代码:

 private void init(Context context,AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleView);
        mRadiu = ta.getDimensionPixelSize(R.styleable.CircleView_radiu,0);
        mBgColor = ta.getColor(R.styleable.CircleView_bg_color,0);
        ta.recycle();
    }

下面写一个下载的环形进度条为例,如图:
获取attrs.xml中声明的自定义属性的值

1、在values文件夹下新建attrs.xml文件,声明要自定义的属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleProgressBar">
        <attr name="progress_color" format="color"/>
        <attr name="background_color" format="color"/>
        <attr name="stroke_width" format="dimension"/>
        <attr name="max_value" format="integer"/>
        <attr name="current_value" format="integer"/>
        <attr name="text_size" format="dimension"/>
        <attr name="text_color" format="color"/>
    </declare-styleable>
</resources>

2、写自定义的view

public class CircleProgressBar extends View {

    public static int TOTAL_DURATION = 10000;
    public static int DEFAULT_PROGRESS_COLOR = Color.BLUE;
    public static int DEFAULT_BACKGROUND_COLOR = Color.GRAY;
    public static int DEFAULT_STROKE_WIDTH = ScreenSizeUtil.dpToPx(40);
    public static int DEFAULT_TEXT_SIZE =  ScreenSizeUtil.spToPx(28);
    public static int DEFAULT_TEXT_COLOR = Color.BLACK;

    private Paint mBackgroundPaint = new Paint();
    private Paint mPaint = new Paint();
    private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private int mProgressColor;
    private int mBackgroundColor;
    private int mStrokeWidth;

    private int mMaxValue = 100;
    private int mCurrentValue = 0;

    private int mCircleRadius;
    private Point mCenterPoint; //环形进度条的原点坐标

    private RectF mOval = new RectF();

    private ValueAnimator mAnimator;
    private boolean isAnimating = false;

    private String mProgress = "";

    private ProgressChangeListener mListener;

    public CircleProgressBar(Context context) {
        super(context);
        init(context, null);
    }

    public CircleProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
        mProgressColor = ta.getColor(R.styleable.CircleProgressBar_progress_color, DEFAULT_PROGRESS_COLOR);
        mBackgroundColor = ta.getColor(R.styleable.CircleProgressBar_background_color, DEFAULT_BACKGROUND_COLOR);
        mStrokeWidth = ta.getDimensionPixelSize(R.styleable.CircleProgressBar_stroke_width, DEFAULT_STROKE_WIDTH);
        mMaxValue = ta.getInt(R.styleable.CircleProgressBar_max_value, 100);
        mCurrentValue = ta.getInt(R.styleable.CircleProgressBar_current_value, 0);
        int textSize = ta.getDimensionPixelSize(R.styleable.CircleProgressBar_text_size, DEFAULT_TEXT_SIZE);
        int textColor = ta.getColor(R.styleable.CircleProgressBar_text_color, DEFAULT_TEXT_COLOR);
        ta.recycle();

        initPaint(textSize, textColor);
        setProgress(mCurrentValue);
        mCenterPoint = new Point();
    }

    //设置进度条当前值
    public void setProgress(int progress) {
        if (progress > mCurrentValue && progress < 0) {
            return;
        }
        if (isAnimating) {
            isAnimating = false;
            mAnimator.cancel();
        }
        int oldValue = mCurrentValue;
        mCurrentValue = progress;
        startAnimation(oldValue, progress);
    }

    public void stopProgress(){
        if (isAnimating) {
            isAnimating = false;
            mAnimator.cancel();
        }
    }

    private void initPaint(int textSize, int textColor) {
        mTextPaint.setColor(textColor);
        mTextPaint.setTextSize(textSize);
        mTextPaint.setTextAlign(Paint.Align.CENTER);

        mPaint.setColor(mProgressColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mStrokeWidth);

        mBackgroundPaint.setColor(mBackgroundColor);
        mBackgroundPaint.setStyle(Paint.Style.STROKE);
        mBackgroundPaint.setStrokeWidth(mStrokeWidth);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        int height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();

        //Math.min(a, b) 返回a、b中叫较小的一个
        mCircleRadius = (Math.min(width, height) - mStrokeWidth) / 2;
        mCenterPoint.set(width / 2, height / 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mListener != null){
            mProgress = mListener.changeProgress(this,mCurrentValue,mMaxValue);
        }
        canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mCircleRadius, mBackgroundPaint);

        mOval.left = mCenterPoint.x - mCircleRadius;
        mOval.right = mCenterPoint.y + mCircleRadius;
        mOval.top = mCenterPoint.y - mCircleRadius;
        mOval.bottom = mCenterPoint.y + mCircleRadius;

        /** * 画圆弧 drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) * 第一个参数:设置圆弧的形状和大小的范围 * 第二个参数:设置圆弧是从哪个角度来顺时针绘画的 * 第三个参数:设置圆弧扫过的角度 * 第四个参数:设置圆弧在绘画的时候是否经过圆形 */
        canvas.drawArc(mOval, 270, 360 * mCurrentValue / mMaxValue, false, mPaint);

        Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
        float baseline = mOval.top + (mOval.height() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
        canvas.drawText(mProgress, mCenterPoint.x, baseline, mTextPaint);
    }

    private void startAnimation(int start, int end) {
        mAnimator = ValueAnimator.ofInt(start, end);
        int duration = Math.abs(TOTAL_DURATION * (end - start) / mMaxValue);

        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurrentValue = (int) animation.getAnimatedValue();
                invalidate();
            }
        });

        mAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                isAnimating = true;
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                isAnimating = false;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });

        mAnimator.setDuration(duration);
        mAnimator.start();
    }

    public interface ProgressChangeListener{
        String changeProgress(CircleProgressBar bar,int currentValue,int maxValue);
    }

    public void setOnProgressChangeListener(ProgressChangeListener progressChangeListener){
        this.mListener = progressChangeListener;
    }

}

3、使用:

public class MainActivity extends AppCompatActivity {

    private CircleProgressBar mBar;
    private Button mStartBtn, mResumeBtn,mStopBtn;

    private int count;

    protected static final int STOP = 0x10000;
    protected static final int NEXT = 0x10001;

    private Handler myHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case STOP:
                    break;
                case NEXT:
                    if (!Thread.currentThread().isInterrupted()) {
                        mBar.setProgress(count);
                    }
            }
        }
    };

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

        initView();
        setClick();
    }

    private void initView() {
        mBar = (CircleProgressBar) findViewById(R.id.bar);
        mStartBtn = (Button) findViewById(R.id.btn_start);
        mResumeBtn = (Button) findViewById(R.id.btn_resume);
        mStopBtn = (Button) findViewById(R.id.btn_stop);

        mBar.setOnProgressChangeListener(new CircleProgressBar.ProgressChangeListener() {
            @Override
            public String changeProgress(CircleProgressBar bar, int currentValue, int maxValue) {
                return 100 * currentValue / maxValue + "%";
            }
        });
    }

    private void setClick() {
        mStartBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                count = 0;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 20; i++) {
                            try {
                                count = (i + 1) * 5;
                                if (i == 19) {
                                    Message msg = new Message();
                                    msg.what = STOP;
                                    myHandler.sendMessage(msg);
                                } else {
                                    Message msg = new Message();
                                    msg.what = NEXT;
                                    myHandler.sendMessage(msg);
                                }

                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
            }
        });

        mResumeBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mBar.setProgress(0);
            }
        });

        mStopBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mBar.stopProgress();
            }
        });
    }

}