国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

自定義一個帶進度值的圓形進度條

2019-11-06 09:48:20
字體:
來源:轉載
供稿:網友

項目中有時候我們為了博得用戶的眼球,需要自定義一些好看的控件,下面記錄一個自定義帶進度值的圓形進度條

先上效果

下面記錄具體的實現過程

在Android studio下新建一個PRoject,然后新建一個CircleProgressView,繼承系統的view,然后重寫它的三個構造方法,如下:

    public CircleProgressView(Context context) {        this(context,null);    }    public CircleProgressView(Context context, AttributeSet attrs) {        this(context, attrs,0);    }    public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mContext = context;    }然后在定義圓形角度條需要的一些參數:

    private Context mContext;    private Paint mBackgroudPaint;//圓的畫筆    private Paint mFrontPaint;//進度條的畫筆    private Paint mTextPaint;//數字的畫筆    private int mWidth;//控件的寬度    private int mHeight;//控件的高度    private  float redis = 200;//默認圓的半徑    private float roundWidth = 50;//默認圓形進度的寬度    private float textSize = 50;//默認字體的大小    private int progress = 0;//記錄進度值    private int maxProgress = 100;//最大進度值    private int backProgressColor = 0xff778899;//默認背景的顏色    private int roundProgressColor = 0xff00BFFF;//默認圓形進度條的顏色    private int textColor = 0xff008080;//默認字體的顏色    private int mXCenter;//圓心的x坐標    private int mYCenter;//圓心的Y坐標我們先不自定義屬性,先在代碼中使用默認的值。寫一個方法,得到手機的中心點,我們要以這個中心點繪制圓

 /**     * 得到屏幕的中心點     */    private void getPhoneCenter(){        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);        mXCenter = wm.getDefaultDisplay().getWidth()/2;        mYCenter = wm.getDefaultDisplay().getHeight()/2;    }然后在構造方法中調用getPhoneCenter()方法,獲取到中心點的坐標。

得到中心點的坐標后,就可以開始繪制了,重寫onDraw()方法,在onDraw()方法中,我們分別繪制背景圓,進度條的扇形,和進度值的數字

先繪制背景圓:

        mBackgroudPaint = new Paint();//初始化背景畫筆        mBackgroudPaint.setColor(backProgressColor);        mBackgroudPaint.setAlpha(100);//透明度   0~255  從完全透明到不透明        mBackgroudPaint.setAntiAlias(true);//消除鋸齒        mBackgroudPaint.setStyle(Paint.Style.FILL);//實心圓        canvas.drawCircle(mXCenter,mYCenter,redis,mBackgroudPaint);//制定中心點的坐標,半徑然后在繪制進度值的數字

        mTextPaint = new Paint();//初始化數字的畫筆        mTextPaint.setColor(textColor);//        mTextPaint.setAntiAlias(true);//消除鋸齒        mTextPaint.setTextSize(textSize);//        mTextPaint.setTextAlign(Paint.Align.CENTER);//設置文字的對齊方式        canvas.drawText(progress+"%",mXCenter,mYCenter, mTextPaint);//progress是加載的進度值

最后就是繪制進度條了

        mFrontPaint = new Paint();        mFrontPaint.setColor(roundProgressColor);        mFrontPaint.setAntiAlias(true);//消除鋸齒        mFrontPaint.setStyle(Paint.Style.STROKE);//空心圓        mFrontPaint.setStrokeWidth(roundWidth);        mFrontPaint.setAlpha(200);//透明度         //確定一個矩形的區域        RectF oval = new RectF(mXCenter-redis+roundWidth/2,mYCenter-redis+roundWidth/2,mXCenter+redis-roundWidth/2,mYCenter+redis-roundWidth/2);        progress = (int)((progress*1.0/maxProgress)*360);        /**         * 繪制扇形         * 第一個參數:確定的矩形區域         * 第二個參數:開始繪制的角度,從12點中開始繪制,角度為-90°         * 第三個參數:是否把弧形的2個點連接起來,false:不連接         * 第四個參數:畫筆         */        canvas.drawArc(oval,-90,progress,false,mFrontPaint);然后我們在MainActivity對應的xml文件中添加自定義的CircleProgressView控件(此處的代碼省略)。我們在MainActivity中啟用一個線程來模擬下載,并結合Handle來處理模擬的結果

class MyThread extends Thread{        @Override        public void run() {            for (int i=0;i<100;i++){                Message msg = myHandler.obtainMessage();                msg.what = UPDATE_PROGRESS;                msg.obj = i+1;                myHandler.sendMessage(msg);                try {                    Thread.sleep(100);//休眠100ms                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }Handle接受到每次接受到消息以后,調用CircleProgressView中的setProgress方法,設置進度的變化

private final int UPDATE_PROGRESS = 001;    CircleProgressView circleProgressView = null;     Handler myHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            switch (msg.what){                case 001:                    int progress =(int) msg.obj;                    circleProgressView.setProgress(progress);                    break;            }        }    };那我們就要在CircleProgressView中給progress添加set,get方法,在set方法中,判斷當前的progress是否大于最大值,如果不大于,在重新繪制view

public void setProgress(int progress) {        this.progress = progress;        if(progress<=maxProgress){//判斷progress是否大于maxProgress            invalidate();//調用這個方法,會重新繪制        }    }    public int getProgress() {        return progress;    }先看一下效果:

需要注意的是:這個時候關于圓形進度控件的屬性我們都是在代碼中寫死的,這樣肯定不能達到復用的目的,我們需要把其中一些關鍵的屬性抽取出來,像系統控件的屬性那樣可以在xml中配置

在res/value文件下新建一個attrs.xml的樣式文件,定義以下屬性:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="RoundProgressBar">        <attr name="roundColor" format="color"/> <!-- 背景色-->        <attr name="roundProgressColor" format="color"/><!-- 進度條的顏色-->        <attr name="roundWidth" format="dimension"></attr><!-- 進度條的寬度-->        <attr name="textColor" format="color" /><!-- 字體的顏色-->        <attr name="textSize" format="dimension" /><!-- 字體的大小-->    </declare-styleable></resources>然后我們在CircleProgressView的構造函數中獲取這些屬性,并且賦值。

自定義一個方法,initResource(attrs)獲取自定義的屬性值,并在構造函數中調用

    private void initResource(AttributeSet attrs) {        //獲取我們自定義的文件名,RoundProgressBar是attrs中定義的name        TypedArray mTypeArray = mContext.obtainStyledAttributes(attrs,R.styleable.RoundProgressBar,0,0);        //獲取背景色,如果沒有設置則使用默認        backProgressColor = mTypeArray.getColor(R.styleable.RoundProgressBar_roundColor,backProgressColor);        //獲取進度條顏色,如果沒有設置則使用默認        roundProgressColor = mTypeArray.getColor(R.styleable.RoundProgressBar_roundProgressColor,roundProgressColor);        //獲取背景圓的半徑,如果沒有設置則使用默認        redis = mTypeArray.getDimension(R.styleable.RoundProgressBar_roundWidth,redis);        //進度條的寬度設置為半徑的1/5        roundWidth = redis/5;        //獲取文本的顏色,如果沒有設置則使用默認        textColor = mTypeArray.getColor(R.styleable.RoundProgressBar_textColor,textColor);        //獲取文本的大小,如果沒有設置則使用默認        textSize = mTypeArray.getDimension(R.styleable.RoundProgressBar_textSize,textSize);    }然后我們重寫onMeasure()方法,測量控件的大小

    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWidth = getRealSize(widthMeasureSpec);        mHeight = getRealSize(heightMeasureSpec);    }自定義一個getRealSize()的方法,得到控件的大小

    private int getRealSize(int measureSpec){        float res = -1;        int mode = MeasureSpec.getMode(measureSpec);        int size = MeasureSpec.getSize(measureSpec);        if(mode == MeasureSpec.AT_MOST || mode == MeasureSpec.UNSPECIFIED){            res = redis*2;        }else{            res = size;        }        return (int)res;    }到此代碼寫的已經差不多了。這兒需要注意:

在eclipse中使用自定義屬性,我們要加上

xmlns:app="http://schemas.android.com/apk/res/我們自己定義的view的包名"但是在Android studio中使用的時候這么寫會報錯,提示找不到,我們直接讓它自動搜索,需要這么寫

xmlns:app ="http://schemas.android.com/apk/res-auto"

最后就是在xml中對自定義屬性的使用了

   <main.zhaocd.com.circleprogressview.CircleProgressView        android:id="@+id/my_view"        android:layout_width="600dp"        android:layout_height="600dp"        app:roundWidth="80dp"        app:roundColor="#7f8d9c"        app:roundProgressColor="#07ce7e"        app:textColor="#e21e17"        app:textSize="40dp"        />最后在總結一下,一般自定義view的步驟:

1、創建attrs文件,自定義屬性(如果一開始不能很好的把握需要那些屬性,可以把這一步放到最后)

2、在構造方法中獲取自定義的屬性

3、重寫onMeasure()方法(測量控件的大小)

4、重寫onDraw()方法(具體的繪制,調用invalidate()方法會強制執行onDraw方法)

所有的源代碼下載


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 巴林左旗| 简阳市| 重庆市| 姜堰市| 雷波县| 迁安市| 三台县| 通海县| 丁青县| 类乌齐县| 寻乌县| 白城市| 宜兴市| 宾阳县| 株洲市| 翁源县| 延长县| 寿宁县| 鄂伦春自治旗| 乌兰县| 荆州市| 车致| 游戏| 万全县| 台中市| 安图县| 芮城县| 泉州市| 宜宾市| 青河县| 景东| 古田县| 庆元县| 蕲春县| 宁远县| 乌拉特后旗| 高雄市| 通州区| 贵港市| 孝昌县| 兴和县|