ShadowOverlayHelper.java revision ce4c2014042fe6e4723bab30741039848adcf4be
1254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu/*
2254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * Copyright (C) 2015 The Android Open Source Project
3254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu *
4254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * in compliance with the License. You may obtain a copy of the License at
6254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu *
7254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * http://www.apache.org/licenses/LICENSE-2.0
8254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu *
9254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License
10254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * or implied. See the License for the specific language governing permissions and limitations under
12254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu * the License.
13254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu */
14254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gupackage android.support.v17.leanback.widget;
15254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
16254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.content.Context;
17254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.content.res.Resources;
18254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.graphics.drawable.ColorDrawable;
19254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.graphics.drawable.Drawable;
20254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.os.Build;
21254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.support.v17.leanback.R;
22254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.support.v17.leanback.system.Settings;
23254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.util.AttributeSet;
24254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.view.ViewGroup;
25254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.view.ViewGroup.LayoutParams;
26254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Guimport android.view.View;
27254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
28254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
29254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu/**
3085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * ShadowOverlayHelper is a helper class for shadow, overlay color and rounded corner.
3185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * There are many choices to implement Shadow, overlay color.
3285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * Initialize it with ShadowOverlayHelper.Builder and it decides the best strategy based
3385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * on options user choose and current platform version.
3485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *
354d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu * <li> For shadow:  it may use 9-patch with opticalBounds or Z-value based shadow for
364d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu *                   API >= 21.  When 9-patch is used, it requires a ShadowOverlayContainer
3785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *                   to include 9-patch views.
384d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu * <li> For overlay: it may use ShadowOverlayContainer which overrides draw() or it may
394d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu *                   use setForeground(new ColorDrawable()) for API>=23.  The foreground support
404d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu *                   might be disabled if rounded corner is applied due to performance reason.
414d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu * <li> For rounded-corner:  it uses a ViewOutlineProvider for API>=21.
4285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *
4385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * There are two different strategies: use Wrapper with a ShadowOverlayContainer;
4485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * or apply rounded corner, overlay and rounded-corner to the view itself.  Below is an example
4585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * of how helper is used.
4685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *
4785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * <code>
4885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * ShadowOverlayHelper mHelper = new ShadowOverlayHelper.Builder().
4985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *         .needsOverlay(true).needsRoundedCorner(true).needsShadow(true)
5085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *         .build();
5185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * mHelper.prepareParentForShadow(parentView); // apply optical-bounds for 9-patch shadow.
5285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * mHelper.setOverlayColor(view, Color.argb(0x80, 0x80, 0x80, 0x80));
5385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * mHelper.setShadowFocusLevel(view, 1.0f);
5485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * ...
5585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * View initializeView(View view) {
5685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *     if (mHelper.needsWrapper()) {
5785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *         ShadowOverlayContainer wrapper = mHelper.createShadowOverlayContainer(context);
5885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *         wrapper.wrap(view);
5985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *         return wrapper;
6085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *     } else {
6185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *         mHelper.onViewCreated(view);
6285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *         return view;
6385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *     }
6485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * }
6585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * ...
6685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu *
6785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu * </code>
68254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu */
69254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gupublic final class ShadowOverlayHelper {
70254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
71254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
7285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * Builder for creating ShadowOverlayHelper.
7385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     */
7485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public static final class Builder {
7585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
7685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private boolean needsOverlay;
7785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private boolean needsRoundedCorner;
7885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private boolean needsShadow;
7985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private boolean preferZOrder = true;
8085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private boolean keepForegroundDrawable;
8185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private Options options = Options.DEFAULT;
8285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
8385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
8485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set if needs overlay color.
8585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param needsOverlay   True if needs overlay.
8685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return  The Builder object itself.
8785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
8885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Builder needsOverlay(boolean needsOverlay) {
8985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.needsOverlay = needsOverlay;
9085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
9185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
9285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
9385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
9485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set if needs shadow.
9585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param needsShadow   True if needs shadow.
9685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return  The Builder object itself.
9785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
9885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Builder needsShadow(boolean needsShadow) {
9985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.needsShadow = needsShadow;
10085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
10185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
10285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
10385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
10485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set if needs rounded corner.
10585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param needsRoundedCorner   True if needs rounded corner.
10685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return  The Builder object itself.
10785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
10885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Builder needsRoundedCorner(boolean needsRoundedCorner) {
10985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.needsRoundedCorner = needsRoundedCorner;
11085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
11185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
11285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
11385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
11485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set if prefer z-order shadow.  On old devices,  z-order shadow might be slow,
11585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * set to false to fall back to static 9-patch shadow.  Recommend to read
11685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * from system wide Setting value: see {@link Settings}.
11785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
11885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param preferZOrder   True if prefer Z shadow.  Default is true.
11985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return The Builder object itself.
12085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
12185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Builder preferZOrder(boolean preferZOrder) {
12285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.preferZOrder = preferZOrder;
12385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
12485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
12585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
12685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
12785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set if not using foreground drawable for overlay color.  For example if
12885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * the view has already assigned a foreground drawable for other purposes.
12985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * When it's true, helper will use a ShadowOverlayContainer for overlay color.
13085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
13185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param keepForegroundDrawable   True to keep the original foreground drawable.
13285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return The Builder object itself.
13385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
13485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Builder keepForegroundDrawable(boolean keepForegroundDrawable) {
13585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.keepForegroundDrawable = keepForegroundDrawable;
13685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
13785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
13885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
13985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
14085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set option values e.g. Shadow Z value, rounded corner radius.
14185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
14285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param options   The Options object to create ShadowOverlayHelper.
14385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
14485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Builder options(Options options) {
14585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.options = options;
14685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
14785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
14885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
14985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
15085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Create ShadowOverlayHelper object
15185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param context    The context uses to read Resources settings.
15285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return           The ShadowOverlayHelper object.
15385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
15485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public ShadowOverlayHelper build(Context context) {
15585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            final ShadowOverlayHelper helper = new ShadowOverlayHelper();
15685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            helper.mNeedsOverlay = needsOverlay;
15785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            helper.mNeedsRoundedCorner = needsRoundedCorner && supportsRoundedCorner();
15885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            helper.mNeedsShadow = needsShadow && supportsShadow();
15985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
16085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            if (helper.mNeedsRoundedCorner) {
16185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                helper.setupRoundedCornerRadius(options, context);
16285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            }
16385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
16485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            // figure out shadow type and if we need use wrapper:
16585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            if (helper.mNeedsShadow) {
16685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                // if static shadow is prefered or dynamic shadow is not supported,
16785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                // use static shadow,  otherwise use dynamic shadow.
16885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                if (!preferZOrder || !supportsDynamicShadow()) {
16985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    helper.mShadowType = SHADOW_STATIC;
17085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    // static shadow requires ShadowOverlayContainer to support crossfading
17185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    // of two shadow views.
17285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    helper.mNeedsWrapper = true;
17385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                } else {
17485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    helper.mShadowType = SHADOW_DYNAMIC;
17585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    helper.setupDynamicShadowZ(options, context);
17685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    helper.mNeedsWrapper = ((!supportsForeground() || keepForegroundDrawable)
17785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                            && helper.mNeedsOverlay);
17885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                }
17985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            } else {
18085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                helper.mShadowType = SHADOW_NONE;
18185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                helper.mNeedsWrapper = ((!supportsForeground() || keepForegroundDrawable)
18285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                        && helper.mNeedsOverlay);
18385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            }
18485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
18585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return helper;
18685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
18785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
18885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    }
18985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
19085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    /**
19185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * Option values for ShadowOverlayContainer.
19285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     */
19385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public static final class Options {
19485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
19585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
19685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Default Options for values.
19785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
19885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public static final Options DEFAULT = new Options();
19985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
20085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private int roundedCornerRadius = 0; // 0 for default value
20185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private float dynamicShadowUnfocusedZ = -1; // < 0 for default value
20285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        private float dynamicShadowFocusedZ = -1;   // < 0 for default value
20385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
20485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set value of rounded corner radius.
20585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
20685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param roundedCornerRadius   Number of pixels of rounded corner radius.
20785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *                              Set to 0 to use default settings.
20885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return  The Options object itself.
20985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
21085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Options roundedCornerRadius(int roundedCornerRadius){
21185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.roundedCornerRadius = roundedCornerRadius;
21285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
21385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
21485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
21585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
21685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Set value of focused and unfocused Z value for shadow.
21785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
21885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param unfocusedZ   Number of pixels for unfocused Z value.
21985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @param focusedZ     Number of pixels for foucsed Z value.
22085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return  The Options object itself.
22185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
22285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public Options dynamicShadowZ(float unfocusedZ, float focusedZ){
22385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.dynamicShadowUnfocusedZ = unfocusedZ;
22485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            this.dynamicShadowFocusedZ = focusedZ;
22585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return this;
22685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
22785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
22885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
22985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Get radius of rounded corner in pixels.
23085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
23185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return Radius of rounded corner in pixels.
23285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
23385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public final int getRoundedCornerRadius() {
23485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return roundedCornerRadius;
23585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
23685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
23785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
23885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Get z value of shadow when a view is not focused.
23985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
24085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return Z value of shadow when a view is not focused.
24185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
24285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public final float getDynamicShadowUnfocusedZ() {
24385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return dynamicShadowUnfocusedZ;
24485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
24585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
24685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        /**
24785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * Get z value of shadow when a view is focused.
24885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         *
24985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         * @return Z value of shadow when a view is focused.
25085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu         */
25185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        public final float getDynamicShadowFocusedZ() {
25285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            return dynamicShadowFocusedZ;
25385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
25485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    }
25585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
25685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    /**
257254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * No shadow.
258254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
259254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public static final int SHADOW_NONE = 1;
260254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
261254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
262254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * Shadows are fixed.
263254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
264254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public static final int SHADOW_STATIC = 2;
265254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
266254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
267254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * Shadows depend on the size, shape, and position of the view.
268254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
269254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public static final int SHADOW_DYNAMIC = 3;
270254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
271254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    int mShadowType = SHADOW_NONE;
272254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    boolean mNeedsOverlay;
273254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    boolean mNeedsRoundedCorner;
274254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    boolean mNeedsShadow;
275254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    boolean mNeedsWrapper;
276254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
27785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    int mRoundedCornerRadius;
278254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    float mUnfocusedZ;
279254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    float mFocusedZ;
280254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
281254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
282254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * Return true if the platform sdk supports shadow.
283254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
284254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public static boolean supportsShadow() {
285254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        return StaticShadowHelper.getInstance().supportsShadow();
286254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
287254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
288254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
289254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * Returns true if the platform sdk supports dynamic shadows.
290254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
291254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public static boolean supportsDynamicShadow() {
292254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        return ShadowHelper.getInstance().supportsDynamicShadow();
293254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
294254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
295254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
296254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * Returns true if the platform sdk supports rounded corner through outline.
297254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
298254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public static boolean supportsRoundedCorner() {
299254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        return RoundedRectHelper.supportsRoundedCorner();
300254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
301254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
302254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
303254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * Returns true if view.setForeground() is supported.
304254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
305254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public static boolean supportsForeground() {
306254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        return ForegroundHelper.supportsForeground();
307254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
308254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
30985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    /*
31085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * hide from external, should be only created by ShadowOverlayHelper.Options.
311254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
31285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    ShadowOverlayHelper() {
313254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
314254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
315254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
316254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * {@link #prepareParentForShadow(ViewGroup)} must be called on parent of container
317254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * before using shadow.  Depending on Shadow type, optical bounds might be applied.
318254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
319254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public void prepareParentForShadow(ViewGroup parent) {
320254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        if (mShadowType == SHADOW_STATIC) {
321254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            StaticShadowHelper.getInstance().prepareParent(parent);
322254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        }
323254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
324254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
325254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public int getShadowType() {
326254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        return mShadowType;
327254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
328254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
329254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public boolean needsOverlay() {
330254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        return mNeedsOverlay;
331254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
332254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
333254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public boolean needsRoundedCorner() {
334254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        return mNeedsRoundedCorner;
335254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
336254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
33785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    /**
33885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * Returns true if a "wrapper" ShadowOverlayContainer is needed.
33985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * When needsWrapper() is true,  call {@link #createShadowOverlayContainer(Context)}
34085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * to create the wrapper.
34185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     */
34285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public boolean needsWrapper() {
34385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        return mNeedsWrapper;
344254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
345254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
34685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    /**
34785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * Create ShadowOverlayContainer for this helper.
34885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * @param context   Context to create view.
34985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * @return          ShadowOverlayContainer.
35085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     */
35185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public ShadowOverlayContainer createShadowOverlayContainer(Context context) {
35285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        if (!needsWrapper()) {
35385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            throw new IllegalArgumentException();
35485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
35585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        return new ShadowOverlayContainer(context, mShadowType, mNeedsOverlay,
35685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                mUnfocusedZ, mFocusedZ, mRoundedCornerRadius);
357254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
358254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
3594d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu    /**
36085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * Set overlay color for view other than ShadowOverlayContainer.
36185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * See also {@link ShadowOverlayContainer#setOverlayColor(int)}.
3624d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu     */
36385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public static void setNoneWrapperOverlayColor(View view, int color) {
3644d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        Drawable d = ForegroundHelper.getInstance().getForeground(view);
3654d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        if (d instanceof ColorDrawable) {
3664d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu            ((ColorDrawable) d).setColor(color);
367254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        } else {
3684d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu            ForegroundHelper.getInstance().setForeground(view, new ColorDrawable(color));
369254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        }
370254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
371254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
372254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
37385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * Set overlay color for view, it can be a ShadowOverlayContainer if needsWrapper() is true,
37485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * or other view type.
37585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     */
37685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public void setOverlayColor(View view, int color) {
37785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        if (needsWrapper()) {
37885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            ((ShadowOverlayContainer) view).setOverlayColor(color);
37985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        } else {
38085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            setNoneWrapperOverlayColor(view, color);
38185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
38285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    }
38385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
38485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    /**
38585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * Must be called when view is created for cases {@link #needsWrapper()} is false.
386254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     * @param view
387254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
388254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    public void onViewCreated(View view) {
38985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        if (!needsWrapper()) {
390254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            if (!mNeedsShadow) {
391254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                if (mNeedsRoundedCorner) {
39285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                    RoundedRectHelper.getInstance().setClipToRoundedOutline(view,
39385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                            true, mRoundedCornerRadius);
394254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                }
395254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            } else {
396254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                if (mShadowType == SHADOW_DYNAMIC) {
397254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                    Object tag = ShadowHelper.getInstance().addDynamicShadow(
39885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                            view, mUnfocusedZ, mFocusedZ, mRoundedCornerRadius);
399254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                    view.setTag(R.id.lb_shadow_impl, tag);
400254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                }
401254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            }
402254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        }
403254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
404254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
405254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    /**
406ce4c2014042fe6e4723bab30741039848adcf4beDake Gu     * Set shadow focus level (0 to 1). 0 for unfocused, 1 for fully focused.
4074d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu     * This is for view other than ShadowOverlayContainer.
40885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     * See also {@link ShadowOverlayContainer#setShadowFocusLevel(float)}.
409254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu     */
41085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public static void setNoneWrapperShadowFocusLevel(View view, float level) {
4114d14fb53ebf304ad989afbc57baa71cfcafa4e7aDake Gu        setShadowFocusLevel(getNoneWrapperDyamicShadowImpl(view), SHADOW_DYNAMIC, level);
412254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
413254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu
41485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    /**
415ce4c2014042fe6e4723bab30741039848adcf4beDake Gu     * Set shadow focus level (0 to 1). 0 for unfocused, 1 for fully focused.
41685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu     */
41785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    public void setShadowFocusLevel(View view, float level) {
41885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        if (needsWrapper()) {
41985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            ((ShadowOverlayContainer) view).setShadowFocusLevel(level);
42085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        } else {
42185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            setShadowFocusLevel(getNoneWrapperDyamicShadowImpl(view), SHADOW_DYNAMIC, level);
42285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
42385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    }
42485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
42585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    void setupDynamicShadowZ(Options options, Context context) {
42685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        if (options.getDynamicShadowUnfocusedZ() < 0f) {
42785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            Resources res = context.getResources();
42885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            mFocusedZ = res.getDimension(R.dimen.lb_material_shadow_focused_z);
42985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            mUnfocusedZ = res.getDimension(R.dimen.lb_material_shadow_normal_z);
43085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        } else {
43185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            mFocusedZ = options.getDynamicShadowFocusedZ();
43285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            mUnfocusedZ = options.getDynamicShadowUnfocusedZ();
43385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
43485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    }
43585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
43685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    void setupRoundedCornerRadius(Options options, Context context) {
43785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        if (options.getRoundedCornerRadius() == 0) {
43885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            Resources res = context.getResources();
43985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            mRoundedCornerRadius = res.getDimensionPixelSize(
44085833087b2288e0f002de6b4ebcbc0564839a217Dake Gu                        R.dimen.lb_rounded_rect_corner_radius);
44185833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        } else {
44285833087b2288e0f002de6b4ebcbc0564839a217Dake Gu            mRoundedCornerRadius = options.getRoundedCornerRadius();
44385833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        }
44485833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    }
44585833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
44685833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    static Object getNoneWrapperDyamicShadowImpl(View view) {
44785833087b2288e0f002de6b4ebcbc0564839a217Dake Gu        return view.getTag(R.id.lb_shadow_impl);
44885833087b2288e0f002de6b4ebcbc0564839a217Dake Gu    }
44985833087b2288e0f002de6b4ebcbc0564839a217Dake Gu
450254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    static void setShadowFocusLevel(Object impl, int shadowType, float level) {
451254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        if (impl != null) {
452254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            if (level < 0f) {
453254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                level = 0f;
454254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            } else if (level > 1f) {
455254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                level = 1f;
456254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            }
457254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            switch (shadowType) {
458254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                case SHADOW_DYNAMIC:
459254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                    ShadowHelper.getInstance().setShadowFocusLevel(impl, level);
460254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                    break;
461254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                case SHADOW_STATIC:
462254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                    StaticShadowHelper.getInstance().setShadowFocusLevel(impl, level);
463254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu                    break;
464254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu            }
465254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu        }
466254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu    }
467254b417129de2a8c5612826a152f8a26c8f1d0e8Dake Gu}
468