Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2015 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.support.design.widget;
     18 
     19 import android.animation.Animator;
     20 import android.animation.ObjectAnimator;
     21 import android.animation.StateListAnimator;
     22 import android.annotation.TargetApi;
     23 import android.content.res.ColorStateList;
     24 import android.graphics.PorterDuff;
     25 import android.graphics.drawable.Drawable;
     26 import android.graphics.drawable.LayerDrawable;
     27 import android.graphics.drawable.RippleDrawable;
     28 import android.os.Build;
     29 import android.support.v4.graphics.drawable.DrawableCompat;
     30 import android.support.v4.view.ViewCompat;
     31 import android.view.View;
     32 import android.view.animation.AnimationUtils;
     33 import android.view.animation.Interpolator;
     34 
     35 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     36 class FloatingActionButtonLollipop extends FloatingActionButtonHoneycombMr1 {
     37 
     38     private Drawable mShapeDrawable;
     39     private RippleDrawable mRippleDrawable;
     40     private Drawable mBorderDrawable;
     41 
     42     private Interpolator mInterpolator;
     43 
     44     FloatingActionButtonLollipop(View view, ShadowViewDelegate shadowViewDelegate) {
     45         super(view, shadowViewDelegate);
     46 
     47         if (!view.isInEditMode()) {
     48             mInterpolator = AnimationUtils.loadInterpolator(mView.getContext(),
     49                     android.R.interpolator.fast_out_slow_in);
     50         }
     51     }
     52 
     53     @Override
     54     void setBackgroundDrawable(Drawable originalBackground, ColorStateList backgroundTint,
     55             PorterDuff.Mode backgroundTintMode, int rippleColor, int borderWidth) {
     56         // Now we need to tint the original background with the tint
     57         mShapeDrawable = DrawableCompat.wrap(originalBackground.mutate());
     58         DrawableCompat.setTintList(mShapeDrawable, backgroundTint);
     59         if (backgroundTintMode != null) {
     60             DrawableCompat.setTintMode(mShapeDrawable, backgroundTintMode);
     61         }
     62 
     63         final Drawable rippleContent;
     64         if (borderWidth > 0) {
     65             mBorderDrawable = createBorderDrawable(borderWidth, backgroundTint);
     66             rippleContent = new LayerDrawable(new Drawable[]{mBorderDrawable, mShapeDrawable});
     67         } else {
     68             mBorderDrawable = null;
     69             rippleContent = mShapeDrawable;
     70         }
     71 
     72         mRippleDrawable = new RippleDrawable(ColorStateList.valueOf(rippleColor),
     73                 rippleContent, null);
     74 
     75         mShadowViewDelegate.setBackgroundDrawable(mRippleDrawable);
     76         mShadowViewDelegate.setShadowPadding(0, 0, 0, 0);
     77     }
     78 
     79     @Override
     80     void setBackgroundTintList(ColorStateList tint) {
     81         DrawableCompat.setTintList(mShapeDrawable, tint);
     82         if (mBorderDrawable != null) {
     83             DrawableCompat.setTintList(mBorderDrawable, tint);
     84         }
     85     }
     86 
     87     @Override
     88     void setBackgroundTintMode(PorterDuff.Mode tintMode) {
     89         DrawableCompat.setTintMode(mShapeDrawable, tintMode);
     90     }
     91 
     92     @Override
     93     void setRippleColor(int rippleColor) {
     94         mRippleDrawable.setColor(ColorStateList.valueOf(rippleColor));
     95     }
     96 
     97     @Override
     98     public void setElevation(float elevation) {
     99         ViewCompat.setElevation(mView, elevation);
    100     }
    101 
    102     @Override
    103     void setPressedTranslationZ(float translationZ) {
    104         StateListAnimator stateListAnimator = new StateListAnimator();
    105 
    106         // Animate translationZ to our value when pressed or focused
    107         stateListAnimator.addState(PRESSED_ENABLED_STATE_SET,
    108                 setupAnimator(ObjectAnimator.ofFloat(mView, "translationZ", translationZ)));
    109         stateListAnimator.addState(FOCUSED_ENABLED_STATE_SET,
    110                 setupAnimator(ObjectAnimator.ofFloat(mView, "translationZ", translationZ)));
    111         // Animate translationZ to 0 otherwise
    112         stateListAnimator.addState(EMPTY_STATE_SET,
    113                 setupAnimator(ObjectAnimator.ofFloat(mView, "translationZ", 0f)));
    114 
    115         mView.setStateListAnimator(stateListAnimator);
    116     }
    117 
    118     @Override
    119     void onDrawableStateChanged(int[] state) {
    120         // no-op
    121     }
    122 
    123     @Override
    124     void jumpDrawableToCurrentState() {
    125         // no-op
    126     }
    127 
    128     private Animator setupAnimator(Animator animator) {
    129         animator.setInterpolator(mInterpolator);
    130         return animator;
    131     }
    132 
    133     @Override
    134     CircularBorderDrawable newCircularDrawable() {
    135         return new CircularBorderDrawableLollipop();
    136     }
    137 }
    138