Android的學(xué)習(xí)與實(shí)踐10 (動(dòng)態(tài)餅狀圖的繪制瓣颅,文本的繪制倦逐,以及于進(jìn)度的結(jié)合,波浪線的簡(jiǎn)單繪制)

1 收獲

通過(guò)學(xué)習(xí)這次宫补,又學(xué)到了實(shí)現(xiàn)一種簡(jiǎn)單的動(dòng)畫(huà)檬姥,我們可以通過(guò)繪畫(huà)的方式來(lái)是實(shí)現(xiàn)動(dòng)畫(huà)。通過(guò)這里的學(xué)習(xí)我們不再僅僅局限于Animator或者Animation,在這里我們還可以繪制文本粉怕,通過(guò)學(xué)習(xí)健民,我們也是第一接觸這些新的知識(shí)點(diǎn),當(dāng)然還還是需要我們花費(fèi)很多時(shí)間去理解的贫贝,不僅僅是學(xué)到了荞雏,還要學(xué)會(huì),學(xué)以致用,只有這樣我們才能掌握我們學(xué)到的東西凤优,才會(huì)轉(zhuǎn)化成我們自己的東西悦陋,才能拿出的手。說(shuō)實(shí)話在課堂上我沒(méi)有怎末聽(tīng)懂筑辨,只是有少部分的知識(shí)才聽(tīng)得懂俺驶,但是我知道也許我沒(méi)有聽(tīng)懂的部分也許是重要的,后面雖然來(lái)上課的人越來(lái)越少棍辕,但是希望自己還是能夠堅(jiān)持下去暮现,學(xué)習(xí)是以漫長(zhǎng)的過(guò)程,他也是一個(gè)充滿無(wú)數(shù)可能的過(guò)程3选F艽!

2.技術(shù)

(1)onDraw方法和onMeasure方法以及onSizeChanged方法
(2)筆的屬性
(3)餅狀圖的三種繪制方式
(4)文本的繪制
(5 )波浪線的繪制

3.技術(shù)實(shí)踐及其應(yīng)用

(1)onDraw方法和onMeasure方法以及onSizeChanged方法

我們?cè)诶L制圖的過(guò)程圖的過(guò)程種我們需要知道這個(gè)圖到底是怎么繪制的抚太。實(shí)際上我們繪制的過(guò)程是在onDraw方法中實(shí)現(xiàn)的

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

在這個(gè)方法中我們可以實(shí)現(xiàn)繪制塘幅,當(dāng)然這個(gè)方法只能由系統(tǒng)調(diào)用,我們不能直接調(diào)用這個(gè)方法尿贫,如果我們需要調(diào)用這個(gè)方法 我們需要通過(guò)方法invalidate()方法來(lái)告訴系統(tǒng)我們需要方法onDraw(Canvas canvas)电媳,然后由系統(tǒng)來(lái)幫我們調(diào)用。
onMeasure()方法是系統(tǒng)的自己調(diào)用的庆亡,通過(guò)這方法系統(tǒng)可以得到最終的容器或者是控件的大小匾乓,不管外部設(shè)置多大或者是多小的值,只要一旦在onMeasure()方法里面設(shè)置了值又谋,那磨最終還是依據(jù)onMeasure()方法里面設(shè)置的大小來(lái)拼缝。

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          }

onSizeChanged方法也是一個(gè)系統(tǒng)的方法,他的作用是當(dāng)父容器或者是一些控件的大小變化后就會(huì)調(diào)用此方法彰亥,父容器的大小確定也會(huì)由系統(tǒng)自己調(diào)用咧七。

 @Override//當(dāng)父容器的大小確定后就會(huì)調(diào)用
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
             }

(2)筆的屬性
在我們繪制的過(guò)程必須要的就是繪制的筆,這個(gè)筆用許多的屬性剩愧,接下來(lái)我們就將這些屬性列舉出來(lái)猪叙,以方便使用。
首先我們需要明確我們的筆在哪使用:關(guān)于這個(gè)筆的使用一般是在onDraw()方法中是用仁卷,在使用之前我們要對(duì)筆進(jìn)行初始化也就是對(duì)筆進(jìn)行設(shè)置屬性
paint:
Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);//對(duì)筆進(jìn)行創(chuàng)建
paint.setColor(Color.BLACK);//對(duì)畫(huà)筆的顏色進(jìn)行設(shè)置
paint.setStrokeWidth(20);//對(duì)畫(huà)筆的粗細(xì)進(jìn)行設(shè)置
paint.setAntiAlias(true);//抗鋸齒
paint.setStyle(Paint.Style.STROKE);//將畫(huà)筆設(shè)置為空心(Paint.Style.FILL為實(shí)心)
在筆的使用時(shí)我們一般和cavas一起使用(cavas詳單與是一塊畫(huà))
(3)餅狀圖的三種繪制方式
在本此實(shí)驗(yàn)中我們以畫(huà)餅狀圖為例穴翩。
首先我們需要新建一個(gè)類(lèi)并且要繼承于View,來(lái)管理畫(huà)餅狀圖

image.png

實(shí)現(xiàn)這里的類(lèi)的構(gòu)造方法

 public Testview(Context context) {
        super(context);
    }

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

然后在onDraw是實(shí)現(xiàn)畫(huà)筆一些屬性

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //畫(huà)一條線
        //準(zhǔn)備畫(huà)筆
        Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);//畫(huà)筆顏色
        paint.setStrokeWidth(20);//畫(huà)筆的粗細(xì)
        paint.setAntiAlias(true);//抗鋸齒
        paint.setStyle(Paint.Style.STROKE);//設(shè)置為空心
 

1.通過(guò)添加點(diǎn)擊事件來(lái)改變餅狀圖的進(jìn)度
添加一個(gè)onTouchEven事件锦积,我們通過(guò)點(diǎn)擊就可以實(shí)現(xiàn)

//點(diǎn)擊事件的方式來(lái)實(shí)現(xiàn)餅狀圖的繪制
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction()==MotionEvent.ACTION_DOWN){
            //點(diǎn)擊屏幕畫(huà)一部分
            angle+=speed;
            //控制最大值
            if(angle>360){
                angle=360;
            }
            //告訴系統(tǒng)調(diào)用onDraw方法是自己繪制
            invalidate();
        }
        return true;
    }
   

效果:


錄制_2019_10_27_21_04_09_573.gif

2.通過(guò)動(dòng)畫(huà)的方式來(lái)實(shí)現(xiàn)動(dòng)畫(huà)
我們通過(guò) ValueAnimator來(lái)實(shí)現(xiàn)動(dòng)畫(huà)

//通過(guò)動(dòng)畫(huà)的方式來(lái)實(shí)現(xiàn)動(dòng)畫(huà)
        //創(chuàng)建Animator對(duì)象 設(shè)置范圍0-360
        ValueAnimator va=ValueAnimator.ofInt(0,360);
        va.setDuration(1000);
        va.setRepeatCount(ValueAnimator.INFINITE);
        va.setRepeatMode(ValueAnimator.RESTART);
        //設(shè)置監(jiān)聽(tīng)器 監(jiān)聽(tīng)值的變化 因?yàn)橹凳且恢痹谧兊拿⑴粒晕覀冃枰恢备?        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //獲取某一刻的值
                angle= (int) valueAnimator.getAnimatedValue();

                //刷新
                invalidate();
            }
        });
        //啟動(dòng)動(dòng)畫(huà)
        va.start();

效果:


錄制_2019_10_27_21_11_32_437.gif

3.通過(guò)定時(shí)器來(lái)實(shí)現(xiàn)動(dòng)畫(huà)的繪制

 //創(chuàng)建定時(shí)器
        final Timer t=new Timer();
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                angle+=speed;
                if(angle>360){
                    t.cancel();
                }
                //invalidate();
                postInvalidate();//在子線程里面使用
            }
        },0,100);

效果:

錄制_2019_10_27_21_16_17_120.gif

(4)文本的繪制
在這個(gè)文本的繪制中我們是以油刻表為例來(lái)進(jìn)行實(shí)現(xiàn)文字的繪制,這里的動(dòng)態(tài)圖是與文字有關(guān)的
對(duì)于文本的繪制與上面圖形的繪制不同之處就是我們需要的是我們學(xué)要單獨(dú)創(chuàng)建一個(gè)文字畫(huà)筆丰介,畫(huà)筆與文字畫(huà)筆有著不同的屬性
同樣我們需要畫(huà)筆背蟆,兩種不同顏色的畫(huà)筆以便于畫(huà)進(jìn)度鉴分,這三個(gè)畫(huà)筆都是在在一個(gè)法中實(shí)現(xiàn)的,而這個(gè)方法會(huì)被這個(gè)構(gòu)造方法調(diào)用

private void inite() {
        //背景畫(huà)筆
        bgpaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        bgpaint.setColor(Color.GRAY);
        bgpaint.setStyle(Paint.Style.STROKE);
        bgpaint.setStrokeWidth(40);
        bgpaint.setStrokeCap(Paint.Cap.ROUND);//設(shè)置端頭的類(lèi)型

        //進(jìn)程畫(huà)筆
        progresspaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        progresspaint.setColor(Color.GREEN);
        progresspaint.setStyle(Paint.Style.STROKE);
        progresspaint.setStrokeWidth(40);
        progresspaint.setStrokeCap(Paint.Cap.ROUND);//設(shè)置端頭的類(lèi)型

        //文本畫(huà)筆
        textpaint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
        textpaint.setColor(Color.BLACK);//設(shè)置文本的壓縮
        textpaint.setTextSize(100);//設(shè)置文本的大小
    }

接下來(lái)的一步是非常重要的繪制文本來(lái)說(shuō)
首先要搞懂我們學(xué)要在哪繪制文本


image.png

我們?cè)诶L制文本時(shí)系統(tǒng)是將文本放在了一個(gè)矩形中而文本域矩形的關(guān)系如上圖
然后我們就在onDraw()方法中繪制

 @Override
    protected void onDraw(Canvas canvas) {
        //畫(huà)初始圓
        //確定矩形區(qū)域
        RectF f=new RectF(50,100,getWidth()-50,getWidth()-50);


        //畫(huà)一個(gè)弧形
        canvas.drawArc(f,120,300,false,bgpaint);
        //計(jì)算對(duì)應(yīng)進(jìn)度的角度
        int angle= (int) (progress*300);
        canvas.drawArc(f,120,angle,false,progresspaint);
        //對(duì)應(yīng)文本變化
        String text=(int)(progress*100)+"%";
        //計(jì)算文字的寬度
        int width= (int) textpaint.measureText(text);

        //計(jì)算文字的矩陣 FontMetrics 
       //獲取矩陣
        Paint.FontMetricsInt fo=textpaint.getFontMetricsInt();
        //文字的高度
        int height=fo.bottom-fo.top;
        //計(jì)算向下移動(dòng)的距離  acent/2  acent為負(fù)數(shù)
        int space=-fo.ascent/2;

        //畫(huà)文字
        canvas.drawText(text,getWidth()/2-width/2,getWidth()/2+space,textpaint);
    }

接下來(lái)我們需要進(jìn)行判斷這個(gè)進(jìn)度是否達(dá)到最大值 沒(méi)有到達(dá)最大值我們就繼續(xù)繪制

 public float getProgress() {
        return progress;
    }

    public void setProgress(float progress) {
        this.progress = progress;

        //刷新 重繪
        if(progress<=1.0001){
            invalidate();
        }

    }

我們通過(guò)點(diǎn)擊事件來(lái)觸發(fā)

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        MeterView mv=findViewById(R.id.meter);

        if(event.getAction()==MotionEvent.ACTION_DOWN){
            //更改進(jìn)度值 在原有的基礎(chǔ)上+0.05
            mv.setProgress((float) (mv.getProgress()+0.05));
        }
        return true;
    }

效果:


image.png

image.png

image.png

(5 )波浪線的繪制
在或波浪線之前我們需要搞清楚什么時(shí)path
path是路徑的意思

我們?cè)谶M(jìn)行繪制不規(guī)則圖形是我們需要按照路勁來(lái)進(jìn)行繪制
我們?cè)诶L制波浪線時(shí)我們有兩種不同的方法繪制quadTo()和cubicTo()

首先我們需要路徑和畫(huà)筆带膀,說(shuō)一我們需要?jiǎng)?chuàng)建畫(huà)筆和路徑志珍,在onDraw方法中進(jìn)行創(chuàng)建

 @Override
    protected void onDraw(Canvas canvas) {
        //創(chuàng)建一個(gè)路徑
        Path path=new Path();
        path.moveTo(50,500);//繪制的起始點(diǎn)
        /*
        //1.塞爾曲線
        path.cubicTo(50,500,200,200,350,500);
        path.cubicTo(350,500,500,800,650,500);
        */

       //2.畫(huà)波浪線
        path.quadTo(200,200,350,500);
        path.quadTo(500,800,650,500f);

        //畫(huà)筆
        Paint paint=new Paint();
        paint.setStrokeWidth(10);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        //繪制
        canvas.drawPath(path,paint);
    }

效果:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市垛叨,隨后出現(xiàn)的幾起案子伦糯,更是在濱河造成了極大的恐慌,老刑警劉巖嗽元,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敛纲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡剂癌,警方通過(guò)查閱死者的電腦和手機(jī)淤翔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)佩谷,“玉大人旁壮,你說(shuō)我怎么就攤上這事×找” “怎么了寡具?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵秤茅,是天一觀的道長(zhǎng)稚补。 經(jīng)常有香客問(wèn)我,道長(zhǎng)框喳,這世上最難降的妖魔是什么课幕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮五垮,結(jié)果婚禮上乍惊,老公的妹妹穿的比我還像新娘。我一直安慰自己放仗,他們只是感情好润绎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著诞挨,像睡著了一般莉撇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惶傻,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天棍郎,我揣著相機(jī)與錄音,去河邊找鬼银室。 笑死涂佃,一個(gè)胖子當(dāng)著我的面吹牛励翼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辜荠,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼汽抚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了伯病?” 一聲冷哼從身側(cè)響起殊橙,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎狱从,沒(méi)想到半個(gè)月后膨蛮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡季研,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年敞葛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片与涡。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惹谐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出驼卖,到底是詐尸還是另有隱情氨肌,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布酌畜,位于F島的核電站怎囚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏桥胞。R本人自食惡果不足惜恳守,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贩虾。 院中可真熱鬧催烘,春花似錦、人聲如沸缎罢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)策精。三九已至舰始,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛮寂,已是汗流浹背蔽午。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酬蹋,地道東北人及老。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓抽莱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親骄恶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子食铐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容