[go: nahoru, domu]

19840efe3dbdc7026521da8576574c55120782f6cChris Banes/*
29840efe3dbdc7026521da8576574c55120782f6cChris Banes * Copyright (C) 2015 The Android Open Source Project
39840efe3dbdc7026521da8576574c55120782f6cChris Banes *
49840efe3dbdc7026521da8576574c55120782f6cChris Banes * Licensed under the Apache License, Version 2.0 (the "License");
59840efe3dbdc7026521da8576574c55120782f6cChris Banes * you may not use this file except in compliance with the License.
69840efe3dbdc7026521da8576574c55120782f6cChris Banes * You may obtain a copy of the License at
79840efe3dbdc7026521da8576574c55120782f6cChris Banes *
89840efe3dbdc7026521da8576574c55120782f6cChris Banes *      http://www.apache.org/licenses/LICENSE-2.0
99840efe3dbdc7026521da8576574c55120782f6cChris Banes *
109840efe3dbdc7026521da8576574c55120782f6cChris Banes * Unless required by applicable law or agreed to in writing, software
119840efe3dbdc7026521da8576574c55120782f6cChris Banes * distributed under the License is distributed on an "AS IS" BASIS,
129840efe3dbdc7026521da8576574c55120782f6cChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139840efe3dbdc7026521da8576574c55120782f6cChris Banes * See the License for the specific language governing permissions and
149840efe3dbdc7026521da8576574c55120782f6cChris Banes * limitations under the License.
159840efe3dbdc7026521da8576574c55120782f6cChris Banes */
169840efe3dbdc7026521da8576574c55120782f6cChris Banes
179840efe3dbdc7026521da8576574c55120782f6cChris Banespackage android.support.design.widget;
189840efe3dbdc7026521da8576574c55120782f6cChris Banes
199840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.content.res.ColorStateList;
2080de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banesimport android.content.res.Resources;
21097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banesimport android.graphics.Color;
229840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.graphics.PorterDuff;
236d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banesimport android.graphics.Rect;
249840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.graphics.drawable.Drawable;
25097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banesimport android.graphics.drawable.GradientDrawable;
260ad7ef59b28d8ffafd551d2756b5a8ec47c90682Mark Weiimport android.support.annotation.Nullable;
27cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banesimport android.support.design.R;
28d9770e12c8ff2d4417700492c6616572be897e93Chris Banesimport android.view.ViewTreeObserver;
299840efe3dbdc7026521da8576574c55120782f6cChris Banes
309840efe3dbdc7026521da8576574c55120782f6cChris Banesabstract class FloatingActionButtonImpl {
319840efe3dbdc7026521da8576574c55120782f6cChris Banes
323d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    Drawable mShapeDrawable;
333d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    Drawable mRippleDrawable;
343d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    CircularBorderDrawable mBorderDrawable;
353d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    Drawable mContentBackground;
363d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes
373d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    float mElevation;
383d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    float mPressedTranslationZ;
393d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes
400ad7ef59b28d8ffafd551d2756b5a8ec47c90682Mark Wei    interface InternalVisibilityChangedListener {
410ad7ef59b28d8ffafd551d2756b5a8ec47c90682Mark Wei        public void onShown();
420ad7ef59b28d8ffafd551d2756b5a8ec47c90682Mark Wei        public void onHidden();
430ad7ef59b28d8ffafd551d2756b5a8ec47c90682Mark Wei    }
440ad7ef59b28d8ffafd551d2756b5a8ec47c90682Mark Wei
45be48ed9161c09c4b2178ab6dbe28638222809fc7Chris Banes    static final int SHOW_HIDE_ANIM_DURATION = 200;
46be48ed9161c09c4b2178ab6dbe28638222809fc7Chris Banes
479840efe3dbdc7026521da8576574c55120782f6cChris Banes    static final int[] PRESSED_ENABLED_STATE_SET = {android.R.attr.state_pressed,
489840efe3dbdc7026521da8576574c55120782f6cChris Banes            android.R.attr.state_enabled};
499840efe3dbdc7026521da8576574c55120782f6cChris Banes    static final int[] FOCUSED_ENABLED_STATE_SET = {android.R.attr.state_focused,
509840efe3dbdc7026521da8576574c55120782f6cChris Banes            android.R.attr.state_enabled};
519840efe3dbdc7026521da8576574c55120782f6cChris Banes    static final int[] EMPTY_STATE_SET = new int[0];
529840efe3dbdc7026521da8576574c55120782f6cChris Banes
53fc780bab91bd4275ae2c3b75c3dfb327e008e4dbChris Banes    final VisibilityAwareImageButton mView;
549840efe3dbdc7026521da8576574c55120782f6cChris Banes    final ShadowViewDelegate mShadowViewDelegate;
559840efe3dbdc7026521da8576574c55120782f6cChris Banes
566d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes    private final Rect mTmpRect = new Rect();
57d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
58d9770e12c8ff2d4417700492c6616572be897e93Chris Banes
59fc780bab91bd4275ae2c3b75c3dfb327e008e4dbChris Banes    FloatingActionButtonImpl(VisibilityAwareImageButton view,
60fc780bab91bd4275ae2c3b75c3dfb327e008e4dbChris Banes            ShadowViewDelegate shadowViewDelegate) {
619840efe3dbdc7026521da8576574c55120782f6cChris Banes        mView = view;
629840efe3dbdc7026521da8576574c55120782f6cChris Banes        mShadowViewDelegate = shadowViewDelegate;
639840efe3dbdc7026521da8576574c55120782f6cChris Banes    }
649840efe3dbdc7026521da8576574c55120782f6cChris Banes
65097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes    abstract void setBackgroundDrawable(ColorStateList backgroundTint,
66cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes            PorterDuff.Mode backgroundTintMode, int rippleColor, int borderWidth);
679840efe3dbdc7026521da8576574c55120782f6cChris Banes
689840efe3dbdc7026521da8576574c55120782f6cChris Banes    abstract void setBackgroundTintList(ColorStateList tint);
699840efe3dbdc7026521da8576574c55120782f6cChris Banes
709840efe3dbdc7026521da8576574c55120782f6cChris Banes    abstract void setBackgroundTintMode(PorterDuff.Mode tintMode);
719840efe3dbdc7026521da8576574c55120782f6cChris Banes
729840efe3dbdc7026521da8576574c55120782f6cChris Banes    abstract void setRippleColor(int rippleColor);
739840efe3dbdc7026521da8576574c55120782f6cChris Banes
743d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    final void setElevation(float elevation) {
753d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes        if (mElevation != elevation) {
763d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes            mElevation = elevation;
773d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes            onElevationChanged(elevation);
783d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes        }
793d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    }
803d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes
816d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes    abstract float getElevation();
826d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes
833d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    final void setPressedTranslationZ(float translationZ) {
843d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes        if (mPressedTranslationZ != translationZ) {
853d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes            mPressedTranslationZ = translationZ;
863d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes            onTranslationZChanged(translationZ);
873d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes        }
883d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    }
893d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes
903d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    abstract void onElevationChanged(float elevation);
919840efe3dbdc7026521da8576574c55120782f6cChris Banes
923d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    abstract void onTranslationZChanged(float translationZ);
939840efe3dbdc7026521da8576574c55120782f6cChris Banes
949840efe3dbdc7026521da8576574c55120782f6cChris Banes    abstract void onDrawableStateChanged(int[] state);
959840efe3dbdc7026521da8576574c55120782f6cChris Banes
969840efe3dbdc7026521da8576574c55120782f6cChris Banes    abstract void jumpDrawableToCurrentState();
979840efe3dbdc7026521da8576574c55120782f6cChris Banes
98fc780bab91bd4275ae2c3b75c3dfb327e008e4dbChris Banes    abstract void hide(@Nullable InternalVisibilityChangedListener listener, boolean fromUser);
99be48ed9161c09c4b2178ab6dbe28638222809fc7Chris Banes
100fc780bab91bd4275ae2c3b75c3dfb327e008e4dbChris Banes    abstract void show(@Nullable InternalVisibilityChangedListener listener, boolean fromUser);
101be48ed9161c09c4b2178ab6dbe28638222809fc7Chris Banes
1023d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    final Drawable getContentBackground() {
1033d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes        return mContentBackground;
1043d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes    }
1053d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes
1066d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes    abstract void onCompatShadowChanged();
1076d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes
1086d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes    final void updatePadding() {
1096d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes        Rect rect = mTmpRect;
1106d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes        getPadding(rect);
1116d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes        onPaddingUpdated(rect);
1126d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes        mShadowViewDelegate.setShadowPadding(rect.left, rect.top, rect.right, rect.bottom);
1136d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes    }
1146d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes
1156d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes    abstract void getPadding(Rect rect);
1166d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes
1176d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes    void onPaddingUpdated(Rect padding) {}
1186d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes
119d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    void onAttachedToWindow() {
120d9770e12c8ff2d4417700492c6616572be897e93Chris Banes        if (requirePreDrawListener()) {
121d9770e12c8ff2d4417700492c6616572be897e93Chris Banes            ensurePreDrawListener();
122d9770e12c8ff2d4417700492c6616572be897e93Chris Banes            mView.getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
123d9770e12c8ff2d4417700492c6616572be897e93Chris Banes        }
124d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    }
125d9770e12c8ff2d4417700492c6616572be897e93Chris Banes
126d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    void onDetachedFromWindow() {
127d9770e12c8ff2d4417700492c6616572be897e93Chris Banes        if (mPreDrawListener != null) {
128d9770e12c8ff2d4417700492c6616572be897e93Chris Banes            mView.getViewTreeObserver().removeOnPreDrawListener(mPreDrawListener);
129d9770e12c8ff2d4417700492c6616572be897e93Chris Banes            mPreDrawListener = null;
130d9770e12c8ff2d4417700492c6616572be897e93Chris Banes        }
131d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    }
132d9770e12c8ff2d4417700492c6616572be897e93Chris Banes
133d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    boolean requirePreDrawListener() {
134d9770e12c8ff2d4417700492c6616572be897e93Chris Banes        return false;
135d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    }
136d9770e12c8ff2d4417700492c6616572be897e93Chris Banes
137d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    CircularBorderDrawable createBorderDrawable(int borderWidth, ColorStateList backgroundTint) {
13880de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes        final Resources resources = mView.getResources();
13980de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes        CircularBorderDrawable borderDrawable = newCircularDrawable();
14080de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes        borderDrawable.setGradientColors(
141a577676a64e5353b8ec927117151aa6be84adf66Chris Banes                resources.getColor(R.color.design_fab_stroke_top_outer_color),
142a577676a64e5353b8ec927117151aa6be84adf66Chris Banes                resources.getColor(R.color.design_fab_stroke_top_inner_color),
143a577676a64e5353b8ec927117151aa6be84adf66Chris Banes                resources.getColor(R.color.design_fab_stroke_end_inner_color),
144a577676a64e5353b8ec927117151aa6be84adf66Chris Banes                resources.getColor(R.color.design_fab_stroke_end_outer_color));
14580de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes        borderDrawable.setBorderWidth(borderWidth);
1468603357c9433b9aef1805413a3bfc4a4f8decc50Chris Banes        borderDrawable.setBorderTint(backgroundTint);
147092f4b4fc5610ed1a2c4f5108066726ee59d8f16Chris Banes        return borderDrawable;
14880de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes    }
14980de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes
15080de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes    CircularBorderDrawable newCircularDrawable() {
15180de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes        return new CircularBorderDrawable();
152cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes    }
153d9770e12c8ff2d4417700492c6616572be897e93Chris Banes
154d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    void onPreDraw() {
155d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    }
156d9770e12c8ff2d4417700492c6616572be897e93Chris Banes
157d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    private void ensurePreDrawListener() {
158d9770e12c8ff2d4417700492c6616572be897e93Chris Banes        if (mPreDrawListener == null) {
159d9770e12c8ff2d4417700492c6616572be897e93Chris Banes            mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
160d9770e12c8ff2d4417700492c6616572be897e93Chris Banes                @Override
161d9770e12c8ff2d4417700492c6616572be897e93Chris Banes                public boolean onPreDraw() {
162d9770e12c8ff2d4417700492c6616572be897e93Chris Banes                    FloatingActionButtonImpl.this.onPreDraw();
163d9770e12c8ff2d4417700492c6616572be897e93Chris Banes                    return true;
164d9770e12c8ff2d4417700492c6616572be897e93Chris Banes                }
165d9770e12c8ff2d4417700492c6616572be897e93Chris Banes            };
166d9770e12c8ff2d4417700492c6616572be897e93Chris Banes        }
167d9770e12c8ff2d4417700492c6616572be897e93Chris Banes    }
168097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes
169097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes    GradientDrawable createShapeDrawable() {
170097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes        GradientDrawable d = new GradientDrawable();
171097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes        d.setShape(GradientDrawable.OVAL);
172097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes        d.setColor(Color.WHITE);
173097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes        return d;
174097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes    }
1759840efe3dbdc7026521da8576574c55120782f6cChris Banes}
176