zoukankan      html  css  js  c++  java
  • Android自定义控件之自定义进度条

    在这里插入图片描述

    自定义控件的几个步骤:
    1.在attrs.xml文件声明自定义属性。
    2.在此类中通过TypedArray拿到自定义属性的值。
    3.根据这些值完成onMeasure,onLayout()和onDraw()函数。
    >
    attrs.xml文件
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <attr name="progress_reach" format="color"></attr>
        <attr name="progress_unreach" format="color"></attr>
        <attr name="progress_reach_height" format="dimension"></attr>
        <attr name="progress_unreach_height" format="dimension"></attr>
        <attr name="progress_text_color" format="color"></attr>
        <attr name="progress_text_size" format="dimension"></attr>
        <attr name="progress_text_offset" format="dimension"></attr>
        <attr name="progress_radius" format="dimension"></attr>
        <declare-styleable name="MyProgressBar">
        <attr name="progress_reach"></attr>
        <attr name="progress_unreach"></attr>
        <attr name="progress_reach_height"></attr>
        <attr name="progress_unreach_height"></attr>
        <attr name="progress_text_color" ></attr>
        <attr name="progress_text_size"></attr>
        <attr name="progress_text_offset"></attr>
        </declare-styleable>
        <declare-styleable name="MyRoundProgressBar">
            <attr name="progress_radius"></attr>
            <!--这里是私有属性-->
        </declare-styleable>
    </resources>
    直线进度条MyProgressBar
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.widget.ProgressBar;
    
    import com.example.yang.crazydemo.R;
    
    /**
     * createtime:2019/8/12
     * author:Yang
     * describe:
     */
    public class MyProgressBar extends ProgressBar {
        private static final int  DEFAULT_TEXT_SIZE=10;//sp
        private static final int  DEFAULT_TEXT_COLOR=0xFFFC00D1;
        private static final int  DEFAULT_COLOR_UNREACH=0XFFD3D6DA;
        private static final int  DEFAULT_COLOR_REACH=DEFAULT_TEXT_COLOR;
        private static final int  DEFAULT_HEIGHT_REACH=2;//dp
        private static final int  DEFAULT_HEIGHT_UNREACH=2;//dp
        private static final int  DEFAULT_TEXT_OFFSET=10;//dp
    
    
    
        protected int mTextColor=DEFAULT_TEXT_COLOR;
        protected int mTextSize=Sptopx(DEFAULT_TEXT_SIZE);
        protected int mTextOffset=Dptopx(DEFAULT_TEXT_OFFSET);
        protected int mReachColor=DEFAULT_COLOR_REACH;
        protected int mUnReachColor=DEFAULT_COLOR_UNREACH;
        protected int mReachHeight=Dptopx(DEFAULT_HEIGHT_REACH);
        protected int mUnReachHeight=Dptopx(DEFAULT_HEIGHT_UNREACH);
    
    
        protected Paint mpaint=new Paint();
        protected int mRealWidth;
    
        public MyProgressBar(Context context) {
            this(context,null);
        }
        public MyProgressBar(Context context,AttributeSet attrs) {
            this(context,attrs,0);
        }
        public MyProgressBar(Context context,AttributeSet attrs,int defStyle) {
            super(context,attrs,defStyle);
            ObtainStyleAttrs(attrs);
        }
    
        protected void ObtainStyleAttrs(AttributeSet attrs) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MyProgressBar);
            mTextSize=(int) typedArray.getDimension(R.styleable.MyProgressBar_progress_text_size, mTextSize);
            mReachColor=typedArray.getColor(R.styleable.MyProgressBar_progress_reach, mReachColor);
            mUnReachColor=typedArray.getColor(R.styleable.MyProgressBar_progress_unreach,mUnReachColor);
            mTextColor=typedArray.getColor(R.styleable.MyProgressBar_progress_text_color,mTextColor );
            mTextOffset= (int) typedArray.getDimension(R.styleable.MyProgressBar_progress_text_offset,mTextOffset);
            mUnReachHeight= (int) typedArray.getDimension(R.styleable.MyProgressBar_progress_unreach_height,mUnReachHeight);
            mReachHeight= (int) typedArray.getDimension(R.styleable.MyProgressBar_progress_reach_height,mReachHeight);
            typedArray.recycle();
            mpaint.setTextSize(mTextSize);
        }
        @Override
        protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int widthVal=MeasureSpec.getSize(widthMeasureSpec);
            int height=MeasureHeight(heightMeasureSpec);
            setMeasuredDimension(widthVal, height);
            mRealWidth=getMeasuredWidth()-getPaddingLeft()-getPaddingRight();
    
        }
    
        @Override
        protected synchronized void onDraw(Canvas canvas) {
            canvas.save();
            canvas.translate(getPaddingLeft(), getHeight()/2);
            boolean NOneedUnreach=false;
            float radio=getProgress()*1.0f/getMax();
            String text=getProgress()+"%";
            float textWidth=mpaint.measureText(text);
            float ProgressX=radio*mRealWidth;
            if(ProgressX+textWidth>mRealWidth){
                ProgressX=mRealWidth-textWidth;
                NOneedUnreach=true;
    
            }
            float EndX=ProgressX-mTextOffset/2;
            //绘制reach
            if(EndX>0){
                mpaint.setColor(mReachColor);
                mpaint.setStrokeWidth(mReachHeight);
                canvas.drawLine(0, 0, EndX, 0, mpaint);
            }
            //绘制text
            mpaint.setColor(mTextColor);
            int y= (int) (-(mpaint.ascent()+mpaint.descent())/2);
            canvas.drawText(text, ProgressX, y,mpaint);
            //绘制Unreach
    
            if(!NOneedUnreach){
                mpaint.setColor(mUnReachColor);
                float start=ProgressX+mTextOffset/2+textWidth;
                mpaint.setStrokeWidth(mUnReachHeight);
                canvas.drawLine(start, 0,mRealWidth, 0, mpaint);
            }
            canvas.restore();
        }
    
        private int MeasureHeight(int heightMeasureSpec) {
            int result=0;
            int Mode=MeasureSpec.getMode(heightMeasureSpec);
            int Size=MeasureSpec.getSize(heightMeasureSpec);
            if(Mode==MeasureSpec.EXACTLY){
                result=Size;
            }else{
                int TextSize= (int) (mpaint.descent()-mpaint.ascent());
                result=getPaddingTop()+getPaddingBottom()+Math.max(Math.max(mReachHeight, mUnReachHeight)
                        , Math.abs(TextSize));
                if(Mode==MeasureSpec.AT_MOST){
                    result=Math.min(result, Size);
                }
            }
            return result;
        }
    
        public  int Dptopx(int dpval){
            return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    dpval, getResources().getDisplayMetrics());
        }
        public int Sptopx(int spval){
            return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spval,
                    getResources().getDisplayMetrics());
        }
    
    }
    圆形进度条MyRoundProgressBar
    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 com.example.yang.crazydemo.R;
    
    /**
     * createtime:2019/8/13
     * author:Yang
     * describe:圆形的进度条
     */
    public class MyRoundProgressBar extends MyProgressBar {
        private int mRadius=Dptopx(30);
        private int mMaxPaintWidth;
        public MyRoundProgressBar(Context context) {
            this(context,null);
        }
        public MyRoundProgressBar(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
        public MyRoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            mReachHeight= (int) (2.5f*mUnReachHeight);
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyRoundProgressBar);
            mRadius= (int) typedArray.getDimension(R.styleable.MyRoundProgressBar_progress_radius, mRadius);
            typedArray.recycle();
            mpaint.setAntiAlias(true);
            mpaint.setDither(true);
            mpaint.setStyle(Paint.Style.STROKE);
            mpaint.setStrokeCap(Paint.Cap.ROUND);
        }
    
        @Override
        protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                  mMaxPaintWidth=Math.max(mReachHeight, mUnReachHeight);
                  int expect=2*mRadius+mMaxPaintWidth+getPaddingLeft()+getPaddingRight();
                  int height=resolveSize(expect, heightMeasureSpec);
                  int width=resolveSize(expect,widthMeasureSpec);
                  int realWidth=Math.min(height, width);
                  mRadius=(realWidth-getPaddingRight()-getPaddingLeft()-mMaxPaintWidth)/2;
                  setMeasuredDimension(realWidth, realWidth);
        }
    
    
        @Override
        protected synchronized void onDraw(Canvas canvas) {
            String text=getProgress()+"%";
            int textwidth= (int) mpaint.measureText(text);
            int textheight=(int)(mpaint.descent()+mpaint.ascent())/2;
            canvas.save();
            canvas.translate(getPaddingLeft()+mMaxPaintWidth/2, getPaddingTop()+mMaxPaintWidth/2);
            mpaint.setStyle(Paint.Style.STROKE);
            //绘制unReachbar
            mpaint.setColor(mUnReachColor);
            mpaint.setStrokeWidth(mUnReachHeight);
            canvas.drawCircle(mRadius, mRadius,mRadius , mpaint);
            //绘制Reachbar
            mpaint.setColor(mReachColor);
            mpaint.setStrokeWidth(mReachHeight);
            float sweepAngle=getProgress()*1.0f/getMax()*360;
            canvas.drawArc(new RectF(0,0,2*mRadius,2*mRadius)
                    , 0, sweepAngle, false,mpaint );
            //绘制Text
            mpaint.setStyle(Paint.Style.FILL);
            mpaint.setColor(mTextColor);
            canvas.drawText(text, mRadius-textwidth/2, mRadius-textheight, mpaint);
            canvas.restore();
    
        }
    }
    布局代码(view是包名)
    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView
        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"
        tools:context=".ProgressActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <view.MyProgressBar
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:id="@+id/myprogress_one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:progress="0"
            android:padding="5dp"
            app:progress_reach="@color/Green"
            app:progress_unreach="@color/c3"
            app:progress_text_color="@color/Green"
            app:progress_text_size="16sp"
            android:layout_marginTop="30dp"/>
        <view.MyRoundProgressBar
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:id="@+id/myprogress_three"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:progress="0"
            android:padding="5dp"
            app:progress_radius="80dp"
            android:layout_marginTop="30dp"
            app:progress_text_size="20sp"
            app:progress_text_color="@color/colorPrimaryDark"
            app:progress_reach="@color/colorPrimaryDark"
            app:progress_unreach="@color/c8"
            />
        <view.MyProgressBar
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:id="@+id/myprogress_two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:progress="100"
            android:padding="5dp"
            app:progress_reach="@color/c1"
            app:progress_unreach="@color/WeChat"
            app:progress_text_color="@color/c1"
            app:progress_text_size="16sp"
            android:layout_marginTop="30dp"/>
        <view.MyRoundProgressBar
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:id="@+id/myprogress_four"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:progress="100"
            android:padding="5dp"
            app:progress_radius="60dp"
            android:layout_marginTop="30dp"
            app:progress_text_size="16sp"
            app:progress_text_color="@color/c7"
            app:progress_reach="@color/c7"
            app:progress_unreach="@color/WeChat"
            />
    </LinearLayout>
    </ScrollView>
    Activity使用代码
    import android.os.Handler;
    import android.os.Message;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import view.MyProgressBar;
    import view.MyRoundProgressBar;
    
    
    public class ProgressActivity extends AppCompatActivity {
    private MyProgressBar progressBarone;
    private MyRoundProgressBar myRoundProgressBar;
    private MyProgressBar progressBartwo;
    private MyRoundProgressBar myRoundProgressBartwo;
    private static final int UPDATA_MSG=0x111;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            int ProgressX=progressBarone.getProgress();
            int ProgressY=progressBartwo.getProgress();
            progressBarone.setProgress(++ProgressX);
            myRoundProgressBar.setProgress(++ProgressX);
            progressBartwo.setProgress(--ProgressY);
            myRoundProgressBartwo.setProgress(--ProgressY);
            while(progressBarone.getProgress()>100){
                removeMessages(UPDATA_MSG);
            }
            while (progressBartwo.getProgress()<0){
                removeMessages(UPDATA_MSG);
            }
            handler.sendEmptyMessageDelayed(UPDATA_MSG, 100);
        }
    };
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_progress);
            progressBarone=findViewById(R.id.myprogress_one);
            myRoundProgressBar=findViewById(R.id.myprogress_three);
            progressBartwo=findViewById(R.id.myprogress_two);
            myRoundProgressBartwo=findViewById(R.id.myprogress_four);
            Message msg=new Message();
            msg.what=1;
            handler.sendMessage(msg);
    
        }
    }

    演示效果图

    在这里插入图片描述

  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309541.html
Copyright © 2011-2022 走看看