[Material Design] 教你做一个Material风格、动画的button(MaterialButton)
原創作品,轉載請注明出處:http://blog.csdn.net/qiujuer/article/details/39831451
前段時間Android L 公布了,相信看過公布會了解過的朋友都為當中的 “Material Design” 感到由衷的驚艷吧!至少我是的。
在驚艷之余感到由衷的遺憾,由于其必須在 ”Android L“ 上才干使用。MD。郁悶啊。之后便自己想弄一個點擊動畫試試,此念頭一發不可收拾;干脆一不做二不休,就重寫了一個 ”MaterialButton“ 控件出來。
在這里不討論什么是 :“Material Design” 。
在這里將給大家分享一下我自己弄的 “Material Design” 風格的 ”MaterialButton“ button動畫實現。
預熱一下:
上面的兩張動畫相信大家都看過吧?是不是挺不錯的?反正我是認為手機上有這種動畫是非常爽的,比較手機是用來添加體驗的??墒沁@些動畫僅僅能在Android L 才干體驗到,對于如今國內的 Android 廠商的情況來看,預計谷歌出新的版本號的時候我們就能用上這個 L 版本號了。
以下給大伙看看我做的 “MaterialButton” button:
效果還不錯吧?好了開始開工了。
介紹一下我的工具:“Android Studio” 當然大家用其它也行。
第一步:新建項目(這個隨意。自己搗鼓吧)
第二步:新建自己定義控件:在java目錄上右擊選擇自己定義控件:
取個名字:“MaterialButton”
如今來看看多了一個類(MaterialButton),一個布局文件 “sample_material_button”,一個屬性文件 “attrs_material_button”
到這里第二步完畢了。多了3個文件。
第三步:改動 “MaterialButton” 類:
分為幾步走:刪除演示樣例代碼。又一次繼承自 “Button” 類,復寫 “onTouchEvent()” 方法。完畢后的代碼:
public class MaterialButton extends Button {public MaterialButton(Context context) {super(context);init(null, 0);}public MaterialButton(Context context, AttributeSet attrs) {super(context, attrs);init(attrs, 0);}public MaterialButton(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(attrs, defStyle);}private void init(AttributeSet attrs, int defStyle) {// Load attributesfinal TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaterialButton, defStyle, 0);a.recycle();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);}@Overridepublic boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);}} 是不是感覺干凈多了?到此第三步完畢了。第四步:就是做實際的動畫了,在這里須要給大家說說三個須要注意的東西:
1.點擊事件響應,這個非常好理解,在?“onTouchEvent()” 方法中完畢,在該方法中我們須要完畢的是點擊后啟動一個動畫。同一時候須要獲取到當時點擊的位置。
2.動畫,這里的動畫不是放大動畫而是屬性動畫,說實話 這個要說清楚還真不是一點點就能說清楚的事情。簡單說就是在動畫中能夠控制一個屬性的變化,而在這里來說就是在 “MaterialButton” 類中建立一個寬度和一個顏色的屬性,然后在動畫中控制這兩個屬性的變化。
3.屬性的建立以及屬性的變化區域確定問題。
首先建立兩個屬性:
private Paint backgroundPaint;private float radius;private Property<MaterialButton, Float> mRadiusProperty = new Property<MaterialButton, Float>(Float.class, "radius") {@Overridepublic Float get(MaterialButton object) {return object.radius;}@Overridepublic void set(MaterialButton object, Float value) {object.radius = value;//刷新Canvasinvalidate();}};private Property<MaterialButton, Integer> mBackgroundColorProperty = new Property<MaterialButton, Integer>(Integer.class, "bg_color") {@Overridepublic Integer get(MaterialButton object) {return object.backgroundPaint.getColor();}@Overridepublic void set(MaterialButton object, Integer value) {object.backgroundPaint.setColor(value);}};兩個屬性對照一下能夠發如今半徑的屬性 “set” 操作中調用了 “invalidate()” 方法,該方法的作用是告訴系統刷新當前控件的 “Canvas”。也就是觸發一次:“onDraw(Canvas canvas)” 方法。
然后復寫 “onTouchEvent()” 方法例如以下:
@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN) {//記錄坐標paintX = event.getX();paintY = event.getY();//啟動動畫startAnimator();}return super.onTouchEvent(event);}在該方法中,首先確定是否是點擊下去的事件。然后記錄坐標,并啟動動畫。在啟動動畫方法 “startAnimator()” 方法中。我們這樣寫:
private void startAnimator() {//計算半徑變化區域int start, end;if (getHeight() < getWidth()) {start = getHeight();end = getWidth();} else {start = getWidth();end = getHeight();}float startRadius = (start / 2 > paintY ? start - paintY : paintY) * 1.15f;float endRadius = (end / 2 > paintX ? end - paintX : paintX) * 0.85f;//新建動畫AnimatorSet set = new AnimatorSet();//加入變化屬性set.playTogether(//半徑變化ObjectAnimator.ofFloat(this, mRadiusProperty, startRadius, endRadius),//顏色變化 黑色到透明ObjectAnimator.ofObject(this, mBackgroundColorProperty, new ArgbEvaluator(), Color.BLACK, Color.TRANSPARENT));// 設置時間set.setDuration((long) (1200 / end * endRadius));//先快后慢set.setInterpolator(new DecelerateInterpolator());set.start();}在這一步我們須要知道有些button并非橫向的,所以長不一定大于寬度。所以須要先推斷獲取到最長與最短,然后進行計算獲取到開始的半徑與結束的半徑。這里有一個我的思路圖:
我們知道在 Android 中都是以左上腳為圓心。然后右邊為X正數。下邊為Y正數。
所以建立了如上坐標系。
藍色矩形區域代表button。藍色點代表點擊的點。
灰色矩形代表點擊后的開始區域,然后4邊開始擴散開。以上就是一個簡單的原理。當然思路有些跳躍,假設不懂能夠在下邊評論我都會進行回復的。
第五步:畫畫。對就是畫畫。這一步就是利用上面的半徑和畫筆顏色進行實際的繪制。
這里須要了解的是:
1:畫畫是在:“onDraw(Canvas canvas)” 方法中完畢
2:在畫板(Canvas)上是分層級的。簡單說就是先畫背景然后畫房子,然后畫人。最后畫人的一些小細節 自底向上的流程
3:畫板每次畫 都是新的畫板。預示著你每次都須要從背景畫起然后才到人。在編程中就是每次?“onDraw(Canvas canvas)” 方法中的畫板(Canvas?)都是新的(New)。
說了那么多事實上非常easy,由于復雜的都在上一步中完畢了。
?“onDraw(Canvas canvas)” 源代碼例如以下:
@Overrideprotected void onDraw(Canvas canvas) {canvas.save();canvas.drawCircle(paintX, paintY, radius, backgroundPaint);canvas.restore();super.onDraw(canvas);}在這里我們先保存了畫板的狀態。然后畫一個圓,然后恢復上一次的狀態,然后調用父類進行后面的繪制工作。這里解釋一下:
1.為什么 “super.onDraw(canvas)” 須要放在最后調用?
由于畫板是分層級的,當調用 “super.onDraw(canvas)” 的時候進行的工作是繪制字體那些。假設放在前面調用那么造成的后果是我們的圓會覆蓋到字體上面。
所以我們須要先畫圓背景。
2.為什么僅僅有一次畫圓操作(canvas.drawCircle())?
由于在半徑屬性中調用了?“invalidate()” ,當每次變化半徑值的時候將進行一次 “onDraw(canvas)” 操作,也就畫一次圓,在一定時間內高速反復畫半徑逐漸增大的圓的時候就形成了動畫效果。
最后給出這次控件的代碼:
start - paintY : paintY) * 1.15f; float endRadius = (end / 2 > paintX ? end - paintX : paintX) * 0.85f; //新建動畫 AnimatorSet set = new AnimatorSet(); //加入變化屬性 set.playTogether( //半徑變化 ObjectAnimator.ofFloat(this, mRadiusProperty, startRadius, endRadius), //顏色變化 黑色到透明 ObjectAnimator.ofObject(this, mBackgroundColorProperty, new ArgbEvaluator(), Color.BLACK, Color.TRANSPARENT) ); // 設置時間 set.setDuration((long) (1200 / end * endRadius)); //先快后慢 set.setInterpolator(new DecelerateInterpolator()); set.start(); } private Property<MaterialButton, Float> mRadiusProperty = new Property<MaterialButton, Float>(Float.class, "radius") { @Override public Float get(MaterialButton object) { return object.radius; } @Override public void set(MaterialButton object, Float value) { object.radius = value; //刷新Canvas invalidate(); } }; private Property<MaterialButton, Integer> mBackgroundColorProperty = new Property<MaterialButton, Integer>(Integer.class, "bg_color") { @Override public Integer get(MaterialButton object) { return object.backgroundPaint.getColor(); } @Override public void set(MaterialButton object, Integer value) { object.backgroundPaint.setColor(value); } }; }
當然興許的工作還有:不同的顏色的button,button屬性的問題。
介于大家可能沒有 Android Studio 無法看到效果,特意把 Apk 上傳了,假設Eclipse不知道怎么導入的話 就加我QQ。我給你說一下!
地址:APK
這些我都在個人的項目中完畢了。大家拿去試試:
Genius-Android
進階:[Material Design] MaterialButton 效果進階 動畫自己主動移動進行對齊效果
轉載于:https://www.cnblogs.com/jhcelue/p/6804052.html
總結
以上是生活随笔為你收集整理的[Material Design] 教你做一个Material风格、动画的button(MaterialButton)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法练习-随机数
- 下一篇: 让Lua支持Linq吧