讓低版本的 Android 項目顯示出 Material 風格的點擊效果

   天天都被不一樣的需求糾纏的生活是幸福而又不幸的,這不咱們家親愛的設計師們又讓咱們在低版本的 Android 平臺上實現一下相似於 Material Design 的點擊效果。html

       雖然你們都知道 MaterialDesign 的確好看不少,可是讓咱們爲低版本適配也是一個苦逼的活兒。java

       不過還好,在使用了 nineoldandroids 這個開源庫以後,總算是實現了這個效果。android

       先放出一個 Github 地址,你們若是能夠去那裏看看源碼: https://github.com/Kifile/MaterialView, 可以 Star 一下就更好了。      git

       再給出兩張效果圖,分別是基於 TextView 和 ImageView 的點擊效果:github

圖1 TextView、ImageView應用後的點擊效果示意圖json

1.代碼實現邏輯

       首先咱們分析一下這種點擊效果的實現邏輯。canvas

       點擊效果的處理主要分爲兩個階段:ruby

       a.手指按下:mvc

              當用戶觸摸到控件的時候,首先咱們先讓控件顯示一層淺色遮罩,而後從手指按下位置開始,有一個深色遮罩逐漸擴大至整個控件。maven

       b.手指彈起:

              當用戶鬆開手指以後,這裏存在兩種狀況,一種是深色遮罩已經擴大到了整個控件的範圍,一種是深色遮罩還沒有徹底包圍整個控件。

              對於前一種狀況,咱們簡單作一次透明度變化,讓遮罩逐漸消失便可;

              對於後一種狀況,咱們須要讓深色遮罩從當前的位置快速擴散到整個控件,同時也要作透明度變化,放置遮罩消失太過突兀。

       具體代碼實現邏輯請參看這裏: https://github.com/Kifile/MaterialView/blob/master/materialwidget/src/main/java/com/kifile/materialwidget/MaterialBackgroundDetector.java,MaterialBackgroundDetector 中 onTouchEvent 的處理。

2.使用庫文件實現 Material 點擊效果

       目前我已經將這個項目部署到了 Maven 中心庫中,若是你們對部署的邏輯感興趣,能夠看看這篇文章(一步一步教你分享開源項目到 Maven 中心倉庫),所以若是你們是使用 Android Studio 來開發項目,能夠經過使用如下代碼將本庫進行集成:

 

[ruby]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. dependencies {  
  2.     compile 'com.kifile:MaterialView:1.0'  
  3. }  

       經過在 gradle.build 文件中引入 maven 項目,咱們如今就能夠正式使用這個點擊效果了。

 

       a.繼承你但願實現的控件,代碼以下:

[html]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. public class MaterialImageView extends ImageView {  
  2.     public MaterialImageView(Context context) {  
  3.         super(context);  
  4.         init(null, 0);  
  5.     }  
  6.   
  7.     public MaterialImageView(Context context, AttributeSet attrs) {  
  8.         super(context, attrs);  
  9.         init(attrs, 0);  
  10.     }  
  11.   
  12.     public MaterialImageView(Context context, AttributeSet attrs, int defStyle) {  
  13.         super(context, attrs, defStyle);  
  14.         init(attrs, defStyle);  
  15.     }  
  16. }  


       b.在 init 方法中建立一個 MaterialBackgroundDetector 對象,用於事件委託:

 

 

[html]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. private MaterialBackgroundDetector mDetector;  
  2.   
  3. private void init(AttributeSet attrs, int defStyle) {  
  4.     final TypedArray a = getContext().obtainStyledAttributes(  
  5.             attrs, com.kifile.materialwidget.R.styleable.MaterialTextView, defStyle, 0);  
  6.     int color = a.getColor(com.kifile.materialwidget.R.styleable.MaterialTextView_maskColor, MaterialBackgroundDetector.DEFAULT_COLOR);  
  7.     a.recycle();  
  8.     mDetector = new MaterialBackgroundDetector(getContext(), this, null, color);  
  9. }  


       c.重寫父類方法,將相應事件委託給 mDetector 對象處理

 

 

[html]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. @Override  
  2. protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  3.     super.onSizeChanged(w, h, oldw, oldh);  
  4.     mDetector.onSizeChanged(w, h);  
  5. }  
  6.   
  7. @Override  
  8. public boolean onTouchEvent(MotionEvent event) {  
  9.     boolean superResult = super.onTouchEvent(event);  
  10.     return mDetector.onTouchEvent(event, superResult);  
  11. }  
  12.   
  13. @Override  
  14. protected void onDraw(Canvas canvas) {  
  15.     super.onDraw(canvas);  
  16.     if (isInEditMode()) {  
  17.         return;  
  18.     }  
  19.     mDetector.draw(canvas);  
  20. }  


       d.(可選)將點擊事件的處理也交給 mDetector

 

              當咱們對控件進行點擊的時候,android 自身的點擊事件處理機制會起做用,若是你的點擊回調函數中存在頁面跳轉,那麼你可能會發現,當你進行點擊以後,按鍵中深色遮罩還沒有擴散到整個控件,整個界面就已經跳轉。這樣會致使Material 動畫看起來會在跳轉的一剎那中止。

              爲了解決這種問題,咱們須要在繼承的空間中對點擊事件作處理,咱們先讓 mDetector 接收到點擊請求,當動畫執行完畢以後,再進行分發給控件作點擊處理。

              所以,你須要實現如下代碼:

              1)在 init 方法裏,將 null,改成 this,令控件實現Callback接口

 

[html]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. mDetector = new MaterialBackgroundDetector(getContext(), this, this, color);  


                  2)重寫如下方法:

 

 

[html]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. @Override  
  2. public boolean performClick() {  
  3.     return mDetector.handlePerformClick();  
  4. }  
  5.   
  6. @Override  
  7. public boolean performLongClick() {  
  8.     return mDetector.handlePerformLongClick();  
  9. }  
  10.   
  11. @Override  
  12. public void performClickAfterAnimation() {  
  13.     super.performClick();  
  14. }  
  15.   
  16. @Override  
  17. public void performLongClickAfterAnimation() {  
  18.     super.performLongClick();  
  19. }  

       到目前爲止,你已經成功的完成了整個界面效果的實現,恭喜你!

 

3.關於混淆

       其實不少時候,咱們均可能涉及到對代碼進行混淆,爲了不在混淆過程當中,混淆工具對代碼的處理致使程序應用失敗,咱們須要在混淆配置文件中加入如下代碼:

 

[html]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. -keep class com.kifile.materialwidget.MaterialBackgroundDetector {  
  2.     public void setRadius(...);  
  3.     public void setAlpha(...);  
  4. }  

 

       

       基本上整個代碼的使用流程就到這裏了,感謝你們的閱覽,若是以爲對本身有幫助,還請頂一下。

 

其餘精彩文章文章

 

jQuery教程(10)-DOM樹操做以內容setter和getter方法

android學習筆記(37)使用 DatePickerDialog、TimePickerDialog

 

 

更多關於android開發文章

相關文章
相關標籤/搜索