FocusHighlightHelper.java revision dfd01bbadc107b6b3b2081ddb0236128c425f380
147520b68e50572a9775a662410c5aff8300c8784Craig Stout/*
247520b68e50572a9775a662410c5aff8300c8784Craig Stout * Copyright (C) 2014 The Android Open Source Project
347520b68e50572a9775a662410c5aff8300c8784Craig Stout *
447520b68e50572a9775a662410c5aff8300c8784Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
547520b68e50572a9775a662410c5aff8300c8784Craig Stout * in compliance with the License. You may obtain a copy of the License at
647520b68e50572a9775a662410c5aff8300c8784Craig Stout *
747520b68e50572a9775a662410c5aff8300c8784Craig Stout * http://www.apache.org/licenses/LICENSE-2.0
847520b68e50572a9775a662410c5aff8300c8784Craig Stout *
947520b68e50572a9775a662410c5aff8300c8784Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License
1047520b68e50572a9775a662410c5aff8300c8784Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
1147520b68e50572a9775a662410c5aff8300c8784Craig Stout * or implied. See the License for the specific language governing permissions and limitations under
1247520b68e50572a9775a662410c5aff8300c8784Craig Stout * the License.
1347520b68e50572a9775a662410c5aff8300c8784Craig Stout */
1447520b68e50572a9775a662410c5aff8300c8784Craig Stoutpackage android.support.v17.leanback.widget;
1547520b68e50572a9775a662410c5aff8300c8784Craig Stout
16a83005b70853ea52c5d98910762344de16b850a8Tim Kilbournimport android.graphics.drawable.TransitionDrawable;
1747520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.support.v17.leanback.R;
1847520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.View;
19dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Guimport android.view.ViewGroup;
20dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Guimport android.view.animation.AccelerateDecelerateInterpolator;
21dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Guimport android.view.animation.Interpolator;
22dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Guimport android.animation.TimeAnimator;
2355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stoutimport android.content.res.Resources;
2447520b68e50572a9775a662410c5aff8300c8784Craig Stout
25739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_NONE;
26739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_SMALL;
27739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_MEDIUM;
28739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_LARGE;
29739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
30739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout
3147520b68e50572a9775a662410c5aff8300c8784Craig Stout/**
3247520b68e50572a9775a662410c5aff8300c8784Craig Stout * Setup the behavior how to highlight when a item gains focus.
3347520b68e50572a9775a662410c5aff8300c8784Craig Stout */
3447520b68e50572a9775a662410c5aff8300c8784Craig Stoutpublic class FocusHighlightHelper {
3547520b68e50572a9775a662410c5aff8300c8784Craig Stout
36b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    static class BrowseItemFocusHighlight implements FocusHighlight {
3747520b68e50572a9775a662410c5aff8300c8784Craig Stout        private static final int DURATION_MS = 150;
3847520b68e50572a9775a662410c5aff8300c8784Craig Stout
39b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout        private static float[] sScaleFactor = new float[4];
40b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout
41b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout        private int mScaleIndex;
42b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout
43b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout        BrowseItemFocusHighlight(int zoomIndex) {
44b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout            mScaleIndex = (zoomIndex >= 0 && zoomIndex < sScaleFactor.length) ?
45b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                    zoomIndex : ZOOM_FACTOR_MEDIUM;
4647520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
4747520b68e50572a9775a662410c5aff8300c8784Craig Stout
48dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu        private static void lazyInit(Resources resources) {
49b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout            if (sScaleFactor[ZOOM_FACTOR_NONE] == 0f) {
50b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                sScaleFactor[ZOOM_FACTOR_NONE] = 1f;
51b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                sScaleFactor[ZOOM_FACTOR_SMALL] =
52b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                        resources.getFraction(R.fraction.lb_focus_zoom_factor_small, 1, 1);
53b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                sScaleFactor[ZOOM_FACTOR_MEDIUM] =
54b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                        resources.getFraction(R.fraction.lb_focus_zoom_factor_medium, 1, 1);
55b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                sScaleFactor[ZOOM_FACTOR_LARGE] =
56b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout                        resources.getFraction(R.fraction.lb_focus_zoom_factor_large, 1, 1);
5747520b68e50572a9775a662410c5aff8300c8784Craig Stout            }
5847520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
5947520b68e50572a9775a662410c5aff8300c8784Craig Stout
60b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout        private float getScale(View view) {
61b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout            lazyInit(view.getResources());
62b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout            return sScaleFactor[mScaleIndex];
63b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout        }
64b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout
65dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu        class FocusAnimator implements TimeAnimator.TimeListener {
66dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private final View mView;
67dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private final ShadowOverlayContainer mWrapper;
68dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private final float mScaleDiff;
69dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private float mFocusLevel = 0f;
70dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private float mFocusLevelStart;
71dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private float mFocusLevelDelta;
72dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private final TimeAnimator mAnimator = new TimeAnimator();
73dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            private final Interpolator mInterpolator = new AccelerateDecelerateInterpolator();
74dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu
75dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            void animateFocus(boolean select, boolean immediate) {
76dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                endAnimation();
77dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                final float end = select ? 1 : 0;
78dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                if (immediate) {
79dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    setFocusLevel(end);
80dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                } else if (mFocusLevel != end) {
81dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    mFocusLevelStart = mFocusLevel;
82dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    mFocusLevelDelta = end - mFocusLevelStart;
83dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    mAnimator.start();
84dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                }
85dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            }
86dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu
87dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            FocusAnimator(View view) {
88dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                mView = view;
89dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                mScaleDiff = getScale(view) - 1f;
90dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                if (view instanceof ShadowOverlayContainer) {
91dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    mWrapper = (ShadowOverlayContainer) view;
92dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                } else {
93dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    mWrapper = null;
94dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                }
95dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                mAnimator.setTimeListener(this);
96dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            }
97dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu
98dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            void setFocusLevel(float level) {
99dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                mFocusLevel = level;
100dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                float scale = 1f + mScaleDiff * level;
101dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                mView.setScaleX(scale);
102dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                mView.setScaleY(scale);
103dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                if (mWrapper != null) {
104dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    mWrapper.setShadowFocusLevel(level);
105dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                }
10647520b68e50572a9775a662410c5aff8300c8784Craig Stout            }
107dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu
108dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            float getFocusLevel() {
109dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                return mFocusLevel;
110dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            }
111dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu
112dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            void endAnimation() {
113dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                mAnimator.end();
114dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            }
115dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu
116dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            @Override
117dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
118dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                float fraction;
119dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                if (totalTime >= DURATION_MS) {
120dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    fraction = 1;
121dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    mAnimator.end();
122dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                } else {
123dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    fraction = (float) (totalTime / (double) DURATION_MS);
124892181367d658f347d00ea5e091aa31f086b2a20Dake Gu                }
125dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                if (mInterpolator != null) {
126dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                    fraction = mInterpolator.getInterpolation(fraction);
127dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                }
128dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                setFocusLevel(mFocusLevelStart + fraction * mFocusLevelDelta);
129dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            }
130dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu        };
131dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu
132dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu        private void viewFocused(View view, boolean hasFocus) {
133dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            view.setSelected(hasFocus);
134dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            FocusAnimator animator = (FocusAnimator) view.getTag(R.id.lb_focus_animator);
135dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            if (animator == null) {
136dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                animator = new FocusAnimator(view);
137dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu                view.setTag(R.id.lb_focus_animator, animator);
138892181367d658f347d00ea5e091aa31f086b2a20Dake Gu            }
139dfd01bbadc107b6b3b2081ddb0236128c425f380Dake Gu            animator.animateFocus(hasFocus, false);
14047520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
14147520b68e50572a9775a662410c5aff8300c8784Craig Stout
14247520b68e50572a9775a662410c5aff8300c8784Craig Stout        @Override
14362d36d44e03a3dd0632b156615b04563c62e83c1Dake Gu        public void onItemFocused(View view, boolean hasFocus) {
14447520b68e50572a9775a662410c5aff8300c8784Craig Stout            viewFocused(view, hasFocus);
14547520b68e50572a9775a662410c5aff8300c8784Craig Stout        }
14647520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
14747520b68e50572a9775a662410c5aff8300c8784Craig Stout
14855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    private static HeaderItemFocusHighlight sHeaderItemFocusHighlight =
14955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            new HeaderItemFocusHighlight();
15055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
151a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    private static ActionItemFocusHighlight sActionItemFocusHighlight =
152a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            new ActionItemFocusHighlight();
153a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
15447520b68e50572a9775a662410c5aff8300c8784Craig Stout    /**
15547520b68e50572a9775a662410c5aff8300c8784Craig Stout     * Setup the focus highlight behavior of a focused item in browse list row.
15647520b68e50572a9775a662410c5aff8300c8784Craig Stout     * @param adapter  adapter of the list row.
15747520b68e50572a9775a662410c5aff8300c8784Craig Stout     */
158b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout    public static void setupBrowseItemFocusHighlight(ItemBridgeAdapter adapter, int zoomIndex) {
159b9e89a1544f8cf582f191184fb9b2a4f24e1fa5bCraig Stout        adapter.setFocusHighlight(new BrowseItemFocusHighlight(zoomIndex));
16047520b68e50572a9775a662410c5aff8300c8784Craig Stout    }
16155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
16255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    /**
16355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     * Setup the focus highlight behavior of a focused item in header list.
16455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     * @param adapter  adapter of the header list.
16555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout     */
16655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    public static void setupHeaderItemFocusHighlight(ItemBridgeAdapter adapter) {
16755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        adapter.setFocusHighlight(sHeaderItemFocusHighlight);
16855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
16955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
170a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    /**
171a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn     * Setup the focus highlight behavior of a focused item in an action list.
172a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn     * @param adapter  adapter of the action list.
173a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn     */
174a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    public static void setupActionItemFocusHighlight(ItemBridgeAdapter adapter) {
175a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        adapter.setFocusHighlight(sActionItemFocusHighlight);
176a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    }
177a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
178a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    private static class HeaderItemFocusHighlight implements FocusHighlight {
17955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        private boolean mInitialized;
18055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        private float mSelectScale;
18155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        private float mUnselectAlpha;
18255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        private int mDuration;
18355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
18455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        private void initializeDimensions(Resources res) {
18555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            if (!mInitialized) {
18655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                mSelectScale =
18755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                        Float.parseFloat(res.getString(R.dimen.lb_browse_header_select_scale));
18855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                mUnselectAlpha =
18955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                        Float.parseFloat(res.getString(R.dimen.lb_browse_header_unselect_alpha));
19055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                mDuration =
19155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                        Integer.parseInt(res.getString(R.dimen.lb_browse_header_select_duration));
19255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                mInitialized = true;
19355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            }
19455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
19555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
19655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        private void viewFocused(View view, boolean hasFocus) {
19755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            initializeDimensions(view.getResources());
19855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            if (hasFocus) {
19955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                view.animate().scaleX(mSelectScale).scaleY(mSelectScale)
20055c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                        .alpha(1f)
20155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                        .setDuration(mDuration);
20255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            } else {
20355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                view.animate().scaleX(1f).scaleY(1f)
20455c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                        .alpha(mUnselectAlpha)
20555c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout                        .setDuration(mDuration);
20655c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            }
20755c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
20855c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout
20955c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        @Override
21062d36d44e03a3dd0632b156615b04563c62e83c1Dake Gu        public void onItemFocused(View view, boolean hasFocus) {
21155c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout            viewFocused(view, hasFocus);
21255c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout        }
21355c9ee4b612ffc7b4632b1e4b7b7ab4900cd47c7Craig Stout    }
214a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
215a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    private static class ActionItemFocusHighlight implements FocusHighlight {
216a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        private boolean mInitialized;
217a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        private int mDuration;
218a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
219a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        private void initializeDimensions(Resources res) {
220a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            if (!mInitialized) {
221a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn                mDuration = Integer.parseInt(res.getString(R.dimen.lb_details_overview_action_select_duration));
222a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            }
223a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        }
224a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn
225a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        @Override
22662d36d44e03a3dd0632b156615b04563c62e83c1Dake Gu        public void onItemFocused(View view, boolean hasFocus) {
227a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            initializeDimensions(view.getResources());
228a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            TransitionDrawable td = (TransitionDrawable) view.getBackground();
229a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            if (hasFocus) {
230a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn                td.startTransition(mDuration);
231a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            } else {
232a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn                td.reverseTransition(mDuration);
233a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn            }
234a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn        }
235a83005b70853ea52c5d98910762344de16b850a8Tim Kilbourn    }
23647520b68e50572a9775a662410c5aff8300c8784Craig Stout}
237