2014-06-25 70 views
17

我喜歡全新Android L版本中引入的全新Touch Ripple動畫,這是新版UI哲學Material Design的一部分。L-release前的觸摸漣漪動畫L

你可以找到它的視頻在官方設計規範表面反應在這裏下:http://www.google.com/design/spec/animation/responsive-interaction.html

這基本上是一個暗灰色圓圈,在視圖的中心淡入和成長,如再次淡出,最終以淺灰色填滿整個視野,然後再次消失。

我想添加同樣的動畫到我的應用程序目標ICS的視圖。

我對如何在我的應用程序中添加此動畫有點無知。 http://developer.android.com/training/animation/index.html的官方文檔似乎沒有涵蓋「在視圖內」發生的動畫。 另外,如果可能的話,我不想使用預先繪製的幀動畫(每幀一個PNG資源)。

我該如何去實施呢? 任何幫助,高度讚賞!

+0

我會等到明天(當新的L相關的API將被髮布),所以我們可以看到支持庫中是否會有某些內容來支持它。 –

+0

最好的方法是使用自定義drawable。請參閱我以前的答案:http://stackoverflow.com/questions/24213356/animating-actionbars-icon/24214040#24214040(請務必閱讀對答案的評論) – Budius

回答

18

東西我很快熟起來,很不理想,但是,嘿,它的東西:Gist

基本上繪製基於動畫半徑的圓。爲了得到精確的L效果,應該進行一些調整。有趣的代碼:

@Override 
public boolean onTouchEvent(@NonNull final MotionEvent event) { 
    if (event.getActionMasked() == MotionEvent.ACTION_UP) { 
     mDownX = event.getX(); 
     mDownY = event.getY(); 

     ObjectAnimator animator = ObjectAnimator.ofFloat(this, "radius", 0, getWidth() * 3.0f); 
     animator.setInterpolator(new AccelerateInterpolator()); 
     animator.setDuration(400); 
     animator.start(); 
    } 
    return super.onTouchEvent(event); 
} 

public void setRadius(final float radius) { 
    mRadius = radius; 
    if (mRadius > 0) { 
     RadialGradient radialGradient = new RadialGradient(
       mDownX, 
       mDownY, 
       mRadius * 3, 
       Color.TRANSPARENT, 
       Color.BLACK, 
       Shader.TileMode.MIRROR 
     ); 
     mPaint.setShader(radialGradient); 
    } 
    invalidate(); 
} 

private Path mPath = new Path(); 
private Path mPath2 = new Path(); 

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

    mPath2.reset(); 
    mPath2.addCircle(mDownX, mDownY, mRadius, Path.Direction.CW); 

    canvas.clipPath(mPath2); 

    mPath.reset(); 
    mPath.addCircle(mDownX, mDownY, mRadius/3, Path.Direction.CW); 

    canvas.clipPath(mPath, Region.Op.DIFFERENCE); 

    canvas.drawCircle(mDownX, mDownY, mRadius, mPaint); 
} 

在他們的談話「什麼是Android新功能」,他們談到了這個動畫實際上發生在一個單獨的「渲染線程」,這將使得它首次在L-釋放。這將允許更平滑的動畫,即使UI線程正在膨脹,或者做其他任何昂貴的動作。

+0

謝謝!我想我最終會結合你的答案和Budius的評論。 –

+0

你的想法很棒,但用戶在觸摸按鈕時應該保持漸變,不是嗎? –

+0

沒有渲染線程的前L設備是否會有明顯的性能影響? – Xiao

5

我的回答有點晚了,但我想分享我的解決方案。我創建了另一個名爲TouchEffectAnimator的課程,內容是Niek Haarman的想法。順便感謝哈曼先生。

您可以看到該類和其示例用法on this gist。我也會簡單地解釋它。

該類包含所有必需的方法和變量,並創建Android L(預覽)當前具有的相同動畫。使用此類:

  • 創建自定義視圖。 (以我創建的LinearLayout爲例)
  • 初始化TouchEffectAnimator對象。
  • 定義它的一些屬性,如顏色,效果類型,持續時間和剪輯角大小。
  • 撥打視圖的onTouchEvent中的TouchEffectAnimator方法。
  • 撥打onDraw TouchEffectAnimator的方法在的視圖的onDraw內。

就是這樣。但是這個班級應該做兩件事才能正常工作。

  • 應該有一些OnClickListener的視圖來獲取向上觸摸事件。
  • 應該爲視圖設置自定義或透明背景。如果沒有設置背景,則不顯示動畫。

我希望它也適用於你。

P.S.我爲我的圖書館項目Android FlatUI Kit創建了這個類。你也可以在FlatButton類中看到這個類的用法。

+0

不錯,謝謝你分享這個,我會試着調整你的TouchEffectAnimator,它完美的工作! – 2Dee

+0

除了我觀察到的小的不一致之外,這是令人敬畏的。如果第一次觸摸按鈕是快速按鈕(state_pressed將只有很少的時間),則動畫不適用。 – Sreeraj