前言
Google I/O 2014 發(fā)布 Material Design ,最近也用了一下,給我的感覺就是簡單而不失華麗,在Material Design我想用的最多的就是波紋效果(Ripple),今天我就帶著大家一起來動手搞定這個效果!
效果圖
TODO
先講一下思路:首先我們要獲取點擊的位置,然后以點擊的位置為圓心,在View中畫圓(也可以畫其他圖形),然后畫文字。
代碼如下:
<pre><code>
private void init(Context context) { this.context = context; textPaint = new Paint(); textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.STROKE); textPaint.setColor(Color.parseColor("#ECFAF2")); textPaint.setTextAlign(Paint.Align.CENTER); textPaint.setTextSize(50); textPaint.setTypeface(Typeface.DEFAULT_BOLD); bgPaint = new Paint(); bgPaint.setAntiAlias(true); bgPaint.setStyle(Paint.Style.FILL); bgPaint.setColor(Color.parseColor("#B7B7B7")); }</code></pre>
在init(Context context)里面我們初始化畫筆,Paint即畫筆,在繪圖過程中起到了極其重要的作用,畫筆主要保存了顏色,樣式等繪制信息,指定了如何繪制文本和圖形,畫筆對象有很多設置方法,大體上可以分為兩類,一類與圖形繪制相關,一類與文本繪制相關,在這里呢我只說一下我們這次用到的方法,其余的方法會另開文章來說明。

<pre><code> private boolean isValidClick(float x, float y) { if (x >= 0 && x <= getWidth() && y >= 0 && y <= getHeight()) { return true; } return false; } public boolean onInterceptTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: return true; } return false; } public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!isValidClick(event.getX(), event.getY())) { return false; } return true; case MotionEvent.ACTION_UP: if (!isValidClick(event.getX(), event.getY())) { return false; } centerX = event.getX(); centerY = event.getY(); isfollow = !isfollow; timerHandler.sendEmptyMessageDelayed(time, time); return true; } return false; }</code></pre>
下面我們要確定圓心,也就是從哪里開始畫圓,圓心是我們用手點擊的位置不固定,所以我們要重寫onInterceptTouchEvent和onTouchEvent來獲取點擊的位置,我們還要考慮點擊的位置是否是有效的,isValidClick就是用來判斷是否有效,思路是在控件的寬高之內,之外我們就算無效點擊。如果是有效事件,那我們就把觸摸的位置記錄下來,然后改變我們的狀態(tài),接下來呢就是發(fā)送Handler,在Handler里面我們重繪按鈕,并每次都遞增圓的半徑。

<pre><code>
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); height = getMeasuredHeight(); width = getMeasuredWidth(); Paint.FontMetrics fontMetrics = textPaint.getFontMetrics(); //計算文字高度 float fontHeight = fontMetrics.bottom - fontMetrics.top; //計算文字baseline float textBaseY = height - (height - fontHeight) / 2 - fontMetrics.bottom; canvas.drawColor(isfollow == true ? Color.parseColor("#00CE7E") : Color.parseColor("#B7B7B7")); bgPaint.setColor(isfollow == true ? Color.parseColor("#B7B7B7") : Color.parseColor("#00CE7E")); canvas.drawCircle(centerX, centerY, radius, bgPaint); canvas.drawText(isfollow == true ? "取消啊" : "關注", width / 2, textBaseY, textPaint); }
</code></pre>
先要說下onDraw方法,View中最主要的三個方法是OnMeasure()測量大小,onDraw()畫,onLayout()排放位置。像TextView和Button都是在onDraw里面繪制的。在最初我們就初始化了一個畫筆,那么畫筆有了接一下我們還缺什么?對,就是畫布,Canvas也就是我們的畫布,同Paint這里我只說一下我們用到的方法,其他方法我會在以后的文章中詳細介紹。

<pre><code>
Handler timerHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); radius += 10; if (radius <= width * 2) { timerHandler.sendEmptyMessageDelayed(time, time); invalidate(); } else { radius = -1; } } };
</code></pre>
最后呢就是我們的Hanlder,它的主要作用就是去發(fā)消息更新我們的view,從而實現波紋效果(也可以使用自定義動畫去實現),在這里我們判斷半徑是否大于我們View的2倍寬度,如果大于就停止重繪,否則半徑每次+10并重繪,在這里呢說一下invalidate()方法,調用invalidate方法就會讓我們的View重繪,也就是每調一次都會走onDraw,要注意的是invalidate只能在UI線程中調用,如果想在非UI線程中沖回View需要調用postInvalidate()方法。
源碼下載
趕快去打造你自己的炫酷按View吧!
版權聲明:本文為博主原創(chuàng)文章,未經博主允許不得轉載。