自定义View-打造属于你的炫酷按钮
自定義View-打造屬于你的炫酷按鈕
前言
Google I/O 2014 發(fā)布 Material Design ,最近也用了一下,給我的感覺就是簡單而不失華麗,在Material Design我想用的最多的就是波紋效果(Ripple),今天我就帶著大家一起來動手搞定這個效果!
效果圖
TODO
先講一下思路:首先我們要獲取點擊的位置,然后以點擊的位置為圓心,在View中畫圓(也可以畫其他圖形),然后畫文字。
代碼如下:
public class SpecialEffectsButton extends View {private Context context;private Paint textPaint;private boolean isfollow = false;private Paint bgPaint;private int radius = -1;private int height;private int width;private int time = 1;private float centerX;private float centerY;public SpecialEffectsButton(Context context) {super(context);init(context);}public SpecialEffectsButton(Context context, AttributeSet attrs) {super(context, attrs);init(context);}public SpecialEffectsButton(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}上面說了第一步要獲取我們的點擊的位置(坐標(biāo)XY),我們需要定義一個常量來存儲XY的位置,當(dāng)然也可以使用Point和PointF來記錄,都是可以的,我個人偏好是使用常量,然后就是畫圓,圓心我們聲明了接下來再聲明個半徑,然后呢就是點擊的狀態(tài)(isfollow,是否關(guān)注,進(jìn)入要做就模仿的像一點),最后就是聲明View的寬高。
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"));}
在init(Context context)里面我們初始化畫筆,Paint即畫筆,在繪圖過程中起到了極其重要的作用,畫筆主要保存了顏色,樣式等繪制信息,指定了如何繪制文本和圖形,畫筆對象有很多設(shè)置方法,大體上可以分為兩類,一類與圖形繪制相關(guān),一類與文本繪制相關(guān),在這里呢我只說一下我們這次用到的方法,其余的方法會另開文章來說明。
| setAntiAlias(boolean) | 開啟抗鋸齒(不開啟的話會顯得不平滑) |
| setStyle(Paint.Style.STROKE) | 設(shè)置畫筆的樣式,為FILL,FILL_OR_STROKE,或STROKE |
| setColor(Color) | 設(shè)置畫筆顏色 |
| setTextAlign(Paint.Align.CENTER) | 是實現(xiàn)水平居中 |
| setTextSize(int size) | 設(shè)置文字大小 |
| setTypeface | 設(shè)置字體,DEFAULT常規(guī)字體,DEFAULT_BOLD黑體類型等 |
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;}
下面我們要確定圓心,也就是從哪里開始畫圓,圓心是我們用手點擊的位置不固定,所以我們要重寫onInterceptTouchEvent和onTouchEvent來獲取點擊的位置,我們還要考慮點擊的位置是否是有效的,isValidClick就是用來判斷是否有效,思路是在控件的寬高之內(nèi),之外我們就算無效點擊。如果是有效事件,那我們就把觸摸的位置記錄下來,然后改變我們的狀態(tài),接下來呢就是發(fā)送Handler,在Handler里面我們重繪按鈕,并每次都遞增圓的半徑。
| onTouchEvent | 觸發(fā)觸摸事件 |
| onInterceptTouchEvent | 觸發(fā)攔截觸摸事件 |
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);height = getMeasuredHeight();width = getMeasuredWidth();Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();//計算文字高度float fontHeight = fontMetrics.bottom - fontMetrics.top;//計算文字baselinefloat 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 ? "取消啊" : "關(guān)注", width / 2, textBaseY, textPaint);}
先要說下onDraw方法,View中最主要的三個方法是OnMeasure()測量大小,onDraw()畫,onLayout()排放位置。像TextView和Button都是在onDraw里面繪制的。在最初我們就初始化了一個畫筆,那么畫筆有了接一下我們還缺什么?對,就是畫布,Canvas也就是我們的畫布,同Paint這里我只說一下我們用到的方法,其他方法我會在以后的文章中詳細(xì)介紹。
| drawColor(Color) | 給畫布畫上顏色,也可以理解為帶顏色的畫布 |
| drawCircle(x,y,radius,paint) | 畫圓,參數(shù)依次為:x軸y軸(圓心),半徑和畫筆 |
| drawText(String, x, y, paint)) | 畫文字,參數(shù)依次為:要畫的文字,顯示位置的xy坐標(biāo)和畫筆 |
Handler timerHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);radius += 10;if (radius <= width * 2) {timerHandler.sendEmptyMessageDelayed(time, time);invalidate();} else {radius = -1;}}};
最后呢就是我們的Hanlder,它的主要作用就是去發(fā)消息更新我們的view,從而實現(xiàn)波紋效果(也可以使用自定義動畫去實現(xiàn)),在這里我們判斷半徑是否大于我們View的2倍寬度,如果大于就停止重繪,否則半徑每次+10并重繪,在這里呢說一下invalidate()方法,調(diào)用invalidate方法就會讓我們的View重繪,也就是每調(diào)一次都會走onDraw,要注意的是invalidate只能在UI線程中調(diào)用,如果想在非UI線程中沖回View需要調(diào)用postInvalidate()方法。
源碼下載
趕快去打造你自己的炫酷按View吧!
總結(jié)
以上是生活随笔為你收集整理的自定义View-打造属于你的炫酷按钮的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mac JER10.7.3安装
- 下一篇: java毕业生设计畜牧场信息管理系统计算