自訂View學習之12/1,自訂view學習12

來源:互聯網
上載者:User

自訂View學習之12/1,自訂view學習12

感謝AigeStudio提供的自訂view講解(地址http://blog.csdn.net/aigestudio)下面是我看了Aige的講解之後自己的理解以及demo,有說錯的地方歡迎大家指出。

在這裡自訂一個圓形等級條的view來加強自己對自訂的理解。

思路:
1、需要畫一個背景圓,再需要一個覆蓋在背景圓上面的進度圓。
2、使用線程讓進度圓產生動畫。
3、在進度圓達到圓滿的時候回到原點,給個回調。

現在我們先畫出一個空心圓。

代碼塊
    /** 背景圓的畫筆 */    private Paint paint;    /** 進度條圓的畫筆 */    private Paint paint1;    /** 設定矩陣的座標點 */    private RectF rectF;    /** 螢幕的高度 */    private int width = 0;    /** 園的半徑 */    private int circleRadius = 0;    /** 園的y軸起始座標 */    private int circleStartY = 20;    /** 園的y軸終點座標 起始座標加上園的半徑*2 */    private int circleEndy = 0;    /**我一般喜歡直接寫3個構造方法,方便引用*/    public CircleView(Context context) {        super(context);        init(context);    }    public CircleView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    /**初始化畫筆*/    private void init(Context context){        paint = new Paint();// 布局xml裡面引用        paint1 = new Paint();// 布局xml裡面引用        paint.setAntiAlias(true);// 設定消除鋸齒            paint.setColor(getResources().getColor(R.color.char_circlebackground));        paint.setStyle(Style.STROKE);// 設定圓心掏空        paint.setStrokeWidth(dip2px(context, 10));        // 設定畫筆形狀 圓形,需要先設定畫筆樣式 SYROKE 或者 FILL_AND_STROKE        paint.setStrokeCap(Paint.Cap.ROUND);        paint1.setAntiAlias(true);// 設定消除鋸齒        paint1.setColor(getResources().getColor(R.color.char_circleplan));        paint1.setStyle(Style.STROKE);        paint1.setStrokeWidth(dip2px(context, 10));        paint1.setStrokeCap(Paint.Cap.ROUND);        width = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();        circleRadius = width / 4;        circleEndy = circleStartY + circleRadius * 2;        rectF = new RectF(width / 2 - circleRadius, circleStartY, width / 2 + circleRadius, circleEndy);// 弧形    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 第一個參數是圓的大小,根據矩陣來控制。第二個參數是在哪個點起始,已順時針方向走,所以說90為正下方。0為最右邊。第三個參數是圓的度數360為一圈        canvas.drawArc(rectF, 90, 360, false, paint);        //這裡等級為4/1等級,所以是90        canvas.drawArc(rectF, 90, 90, false, paint1);    }        /**傳入dp,返回px*/    public float dip2px(Context context, float dpValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (float) (dpValue * scale + 0.5f);    }

效果如下:

效果已經畫出來了。但是缺少點東西,現在view裡面東西全是死的,得讓他活起來,並且具有動畫,滿級之後自動反0操作。所以我加了以下代碼

    /** 背景圓的畫筆 */    private Paint paint;    /** 進度條圓的畫筆 */    private Paint paint1;    /** 設定矩陣的座標點 */    private RectF rectF;    /** 螢幕的高度 */    private int width = 0;    /** 園的半徑 */    private int circleRadius = 0;    /** 園的y軸起始座標 */    private int circleStartY = 20;    /** 園的y軸終點座標 起始座標加上園的半徑*2 */    private int circleEndy = 0;    /** 初始進度 */    private float currentPorcent = 0;    /** 進度是多少 */    private float maxPorcent = 0;    /**滿級回調*/    public RestoreCirclr rc;    /** 是否還原 */    public boolean isRestore = false;    /**我一般喜歡直接寫3個構造方法,方便引用*/    public CircleView(Context context) {        super(context);        init(context);    }    public CircleView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    /**初始化畫筆*/    private void init(Context context){        paint = new Paint();// 布局xml裡面引用        paint1 = new Paint();// 布局xml裡面引用        paint.setAntiAlias(true);// 設定消除鋸齒        paint.setColor(getResources().getColor(R.color.char_circlebackground));        paint.setStyle(Style.STROKE);// 設定圓心掏空        paint.setStrokeWidth(dip2px(context, 10));        // 設定畫筆形狀 圓形,需要先設定畫筆樣式 SYROKE 或者 FILL_AND_STROKE        paint.setStrokeCap(Paint.Cap.ROUND);        paint1.setAntiAlias(true);// 設定消除鋸齒        paint1.setColor(getResources().getColor(R.color.char_circleplan));        paint1.setStyle(Style.STROKE);        paint1.setStrokeWidth(dip2px(context, 10));        paint1.setStrokeCap(Paint.Cap.ROUND);        width = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();        circleRadius = width / 4;        circleEndy = circleStartY + circleRadius * 2;        rectF = new RectF(width / 2 - circleRadius, circleStartY, width / 2 + circleRadius, circleEndy);// 弧形    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 第一個參數是圓的大小,根據矩陣來控制。第二個參數是在哪個點起始,已順時針方向走,所以說90為正下方。0為最右邊。第三個參數是圓的度數360為一圈        canvas.drawArc(rectF, 90, 360, false, paint);        //這裡等級為4/1等級,所以是90        canvas.drawArc(rectF, 90, currentPorcent, false, paint1);        if (currentPorcent == 0) {            handler.postDelayed(drawRunnable, 0);        }    }    /**啟動動畫重新整理介面*/    public void invalidateView(){        handler.postDelayed(drawRunnable, 0);    }    private Handler handler = new Handler();    Runnable drawRunnable = new Runnable() {        @Override        public void run() {            if (!isRestore) {//有經驗時動畫                if (currentPorcent >= maxPorcent) {                    currentPorcent = maxPorcent;                    invalidate();                    //移除當前Runnable                    handler.removeCallbacks(drawRunnable);                } else {                    currentPorcent += 5;//這裡是動畫速度,當前為5。可自己去調試經驗值增長速度                    handler.postDelayed(drawRunnable, (long) (1300 / maxPorcent));                    invalidate();                }                if (currentPorcent == 360) {                    if (rc != null) {                        isRestore = rc.OnRestoreCirclr();                        handler.postDelayed(drawRunnable, 0);                    }                }            } else {//滿級之後經驗條動畫返回0進度                if (currentPorcent <= 0) {                    currentPorcent = 0;                    invalidate();                    handler.removeCallbacks(drawRunnable);                } else {                    currentPorcent -= 3;//這裡是動畫速度,當前為3。可自己去調試經驗值反0速度                    handler.postDelayed(drawRunnable, (long) (1300 / maxPorcent));                    invalidate();                }            }        }    };    public boolean isRestore() {        return isRestore;    }    public void setRestore(boolean isRestore) {        this.isRestore = isRestore;    }    /** 設定等級進度,傳入升級經驗,以及當前經驗  maxPorcent就是當前經驗在升級經驗占的百分比*/    public void setCirclePlan(int max, int current) {        maxPorcent = (int) (((float)360 / (float)max) * current);    }    /**傳入dp,返回px*/    public float dip2px(Context context, float dpValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (float) (dpValue * scale + 0.5f);    }       /** 設定園線的顏色 */    public void setCircleColor(int color) {        paint.setColor(color);    }    /** 設定進度線的顏色 */    public void setCirclePlanColor(int color) {        paint1.setColor(color);    }    public void setRc(RestoreCirclr rc) {        this.rc = rc;    }    public interface RestoreCirclr {        public boolean OnRestoreCirclr();    }

在mainActivity裡面調用代碼如下:

    private CircleView circleView;    /** 升級經驗為100 */    private int max ;    /** 目前經驗值為10 */    private int current ;    /** 經驗加10 */    private Button button_1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main_activity);        circleView = (CircleView) findViewById(R.id.circleView);        button_1 = (Button) findViewById(R.id.button_1);        button_1.setOnClickListener(this);        max = 100;        current = 10;        circleView.setCirclePlan(max, current);// 進度條已滿 升級數是100,當前經驗數是10        circleView.setRc(new RestoreCirclr() {// 滿級之後的回調            @Override            public boolean OnRestoreCirclr() {                //滿級之後的操作   返回true就回到原點                current=0;                return true;            }        });    }    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.button_1:            current += 10;            circleView.setRestore(false); //false經驗值增加            circleView.setCirclePlan(max, current);            circleView.invalidateView();//重新整理view            break;        }    }

:
由於本人第一次寫部落格,不會製作那種可動的gif圖片,所以導致動畫效果看不見。如果各位有興趣的看看動畫效果可去(http://download.csdn.net/detail/u013895206/8431395)這個地址下載源碼。
本篇自訂view學習就到這裡,歡迎大家指正錯誤。互相學習。第一次專註的寫部落格,希望各位大大多多支援。提前祝福兄弟姐妹們新年快樂。。

未完待續、、、

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.