FloatingActionButtonImpl.java revision 3d81c900316412b4130bf40e0dd8b0d3d3a93e78
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 17package android.support.design.widget; 18 19import android.content.res.ColorStateList; 20import android.content.res.Resources; 21import android.graphics.Color; 22import android.graphics.PorterDuff; 23import android.graphics.drawable.Drawable; 24import android.graphics.drawable.GradientDrawable; 25import android.support.annotation.Nullable; 26import android.support.design.R; 27import android.view.ViewTreeObserver; 28 29abstract class FloatingActionButtonImpl { 30 31 Drawable mShapeDrawable; 32 Drawable mRippleDrawable; 33 CircularBorderDrawable mBorderDrawable; 34 Drawable mContentBackground; 35 36 float mElevation; 37 float mPressedTranslationZ; 38 39 interface InternalVisibilityChangedListener { 40 public void onShown(); 41 public void onHidden(); 42 } 43 44 static final int SHOW_HIDE_ANIM_DURATION = 200; 45 46 static final int[] PRESSED_ENABLED_STATE_SET = {android.R.attr.state_pressed, 47 android.R.attr.state_enabled}; 48 static final int[] FOCUSED_ENABLED_STATE_SET = {android.R.attr.state_focused, 49 android.R.attr.state_enabled}; 50 static final int[] EMPTY_STATE_SET = new int[0]; 51 52 final VisibilityAwareImageButton mView; 53 final ShadowViewDelegate mShadowViewDelegate; 54 55 private ViewTreeObserver.OnPreDrawListener mPreDrawListener; 56 57 FloatingActionButtonImpl(VisibilityAwareImageButton view, 58 ShadowViewDelegate shadowViewDelegate) { 59 mView = view; 60 mShadowViewDelegate = shadowViewDelegate; 61 } 62 63 abstract void setBackgroundDrawable(ColorStateList backgroundTint, 64 PorterDuff.Mode backgroundTintMode, int rippleColor, int borderWidth); 65 66 abstract void setBackgroundTintList(ColorStateList tint); 67 68 abstract void setBackgroundTintMode(PorterDuff.Mode tintMode); 69 70 abstract void setRippleColor(int rippleColor); 71 72 final void setElevation(float elevation) { 73 if (mElevation != elevation) { 74 mElevation = elevation; 75 onElevationChanged(elevation); 76 } 77 } 78 79 final void setPressedTranslationZ(float translationZ) { 80 if (mPressedTranslationZ != translationZ) { 81 mPressedTranslationZ = translationZ; 82 onTranslationZChanged(translationZ); 83 } 84 } 85 86 abstract void onElevationChanged(float elevation); 87 88 abstract void onTranslationZChanged(float translationZ); 89 90 abstract void onDrawableStateChanged(int[] state); 91 92 abstract void jumpDrawableToCurrentState(); 93 94 abstract void hide(@Nullable InternalVisibilityChangedListener listener, boolean fromUser); 95 96 abstract void show(@Nullable InternalVisibilityChangedListener listener, boolean fromUser); 97 98 final Drawable getContentBackground() { 99 return mContentBackground; 100 } 101 102 void onAttachedToWindow() { 103 if (requirePreDrawListener()) { 104 ensurePreDrawListener(); 105 mView.getViewTreeObserver().addOnPreDrawListener(mPreDrawListener); 106 } 107 } 108 109 void onDetachedFromWindow() { 110 if (mPreDrawListener != null) { 111 mView.getViewTreeObserver().removeOnPreDrawListener(mPreDrawListener); 112 mPreDrawListener = null; 113 } 114 } 115 116 boolean requirePreDrawListener() { 117 return false; 118 } 119 120 CircularBorderDrawable createBorderDrawable(int borderWidth, ColorStateList backgroundTint) { 121 final Resources resources = mView.getResources(); 122 CircularBorderDrawable borderDrawable = newCircularDrawable(); 123 borderDrawable.setGradientColors( 124 resources.getColor(R.color.design_fab_stroke_top_outer_color), 125 resources.getColor(R.color.design_fab_stroke_top_inner_color), 126 resources.getColor(R.color.design_fab_stroke_end_inner_color), 127 resources.getColor(R.color.design_fab_stroke_end_outer_color)); 128 borderDrawable.setBorderWidth(borderWidth); 129 borderDrawable.setBorderTint(backgroundTint); 130 return borderDrawable; 131 } 132 133 CircularBorderDrawable newCircularDrawable() { 134 return new CircularBorderDrawable(); 135 } 136 137 void onPreDraw() { 138 } 139 140 private void ensurePreDrawListener() { 141 if (mPreDrawListener == null) { 142 mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() { 143 @Override 144 public boolean onPreDraw() { 145 FloatingActionButtonImpl.this.onPreDraw(); 146 return true; 147 } 148 }; 149 } 150 } 151 152 GradientDrawable createShapeDrawable() { 153 GradientDrawable d = new GradientDrawable(); 154 d.setShape(GradientDrawable.OVAL); 155 d.setColor(Color.WHITE); 156 return d; 157 } 158} 159