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);
    
        }
    }

    演示效果图

    在这里插入图片描述

  • 相关阅读:
    DNS服务器配置
    动态网站技术CGI
    SED单行脚本快速参考(Unix 流编辑器)
    xen 安静的角落
    IP命令
    oracle 监听文件 说明
    LRU ,LRUW,CKPT-Q
    重建控制文件ORA-12720
    历史备份控制文件恢复数据库
    增量检查点和完全检查点
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309541.html
Copyright © 2011-2022 走看看