Home | History | Annotate | Download | only in drawable
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.graphics.drawable;
     18 
     19 import android.animation.ObjectAnimator;
     20 import android.animation.TimeInterpolator;
     21 import android.graphics.Canvas;
     22 import android.graphics.Paint;
     23 import android.graphics.Rect;
     24 import android.util.FloatProperty;
     25 import android.view.animation.LinearInterpolator;
     26 
     27 /**
     28  * Draws a ripple background.
     29  */
     30 class RippleBackground extends RippleComponent {
     31 
     32     private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
     33 
     34     private static final int OPACITY_DURATION = 80;
     35 
     36     private ObjectAnimator mAnimator;
     37 
     38     private float mOpacity = 0;
     39 
     40     /** Whether this ripple is bounded. */
     41     private boolean mIsBounded;
     42 
     43     private boolean mFocused = false;
     44     private boolean mHovered = false;
     45 
     46     public RippleBackground(RippleDrawable owner, Rect bounds, boolean isBounded) {
     47         super(owner, bounds);
     48 
     49         mIsBounded = isBounded;
     50     }
     51 
     52     public boolean isVisible() {
     53         return mOpacity > 0;
     54     }
     55 
     56     public void draw(Canvas c, Paint p) {
     57         final int origAlpha = p.getAlpha();
     58         final int alpha = Math.min((int) (origAlpha * mOpacity + 0.5f), 255);
     59         if (alpha > 0) {
     60             p.setAlpha(alpha);
     61             c.drawCircle(0, 0, mTargetRadius, p);
     62             p.setAlpha(origAlpha);
     63         }
     64     }
     65 
     66     public void setState(boolean focused, boolean hovered, boolean pressed) {
     67         if (!mFocused) {
     68             focused = focused && !pressed;
     69         }
     70         if (!mHovered) {
     71             hovered = hovered && !pressed;
     72         }
     73         if (mHovered != hovered || mFocused != focused) {
     74             mHovered = hovered;
     75             mFocused = focused;
     76             onStateChanged();
     77         }
     78     }
     79 
     80     private void onStateChanged() {
     81         // Hover             = .2 * alpha
     82         // Focus             = .6 * alpha
     83         // Focused + Hovered = .6 * alpha
     84         float newOpacity = mFocused ? .6f : mHovered ? .2f : 0f;
     85         if (mAnimator != null) {
     86             mAnimator.cancel();
     87             mAnimator = null;
     88         }
     89         mAnimator = ObjectAnimator.ofFloat(this, OPACITY, newOpacity);
     90         mAnimator.setDuration(OPACITY_DURATION);
     91         mAnimator.setInterpolator(LINEAR_INTERPOLATOR);
     92         mAnimator.start();
     93     }
     94 
     95     public void jumpToFinal() {
     96         if (mAnimator != null) {
     97             mAnimator.end();
     98             mAnimator = null;
     99         }
    100     }
    101 
    102     private static abstract class BackgroundProperty extends FloatProperty<RippleBackground> {
    103         public BackgroundProperty(String name) {
    104             super(name);
    105         }
    106     }
    107 
    108     private static final BackgroundProperty OPACITY = new BackgroundProperty("opacity") {
    109         @Override
    110         public void setValue(RippleBackground object, float value) {
    111             object.mOpacity = value;
    112             object.invalidateSelf();
    113         }
    114 
    115         @Override
    116         public Float get(RippleBackground object) {
    117             return object.mOpacity;
    118         }
    119     };
    120 }
    121