FocusHighlightHelper.java revision 892181367d658f347d00ea5e091aa31f086b2a20
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14package android.support.v17.leanback.widget;
15
16import android.graphics.drawable.TransitionDrawable;
17import android.support.v17.leanback.R;
18import android.view.View;
19import android.content.res.Resources;
20
21/**
22 * Setup the behavior how to highlight when a item gains focus.
23 */
24public class FocusHighlightHelper {
25
26    static class BrowseItemFocusHighlight implements FocusHighlight {
27        private static final int DURATION_MS = 150;
28
29        public static int ZOOM_FACTOR_NONE = 0;
30        public static int ZOOM_FACTOR_SMALL = 1;
31        public static int ZOOM_FACTOR_MEDIUM = 2;
32        public static int ZOOM_FACTOR_LARGE = 3;
33
34        private static float[] sScaleFactor = new float[4];
35
36        private int mScaleIndex;
37
38        BrowseItemFocusHighlight(int zoomIndex) {
39            mScaleIndex = (zoomIndex >= 0 && zoomIndex < sScaleFactor.length) ?
40                    zoomIndex : ZOOM_FACTOR_MEDIUM;
41        }
42
43        private void lazyInit(Resources resources) {
44            if (sScaleFactor[ZOOM_FACTOR_NONE] == 0f) {
45                sScaleFactor[ZOOM_FACTOR_NONE] = 1f;
46                sScaleFactor[ZOOM_FACTOR_SMALL] =
47                        resources.getFraction(R.fraction.lb_focus_zoom_factor_small, 1, 1);
48                sScaleFactor[ZOOM_FACTOR_MEDIUM] =
49                        resources.getFraction(R.fraction.lb_focus_zoom_factor_medium, 1, 1);
50                sScaleFactor[ZOOM_FACTOR_LARGE] =
51                        resources.getFraction(R.fraction.lb_focus_zoom_factor_large, 1, 1);
52            }
53        }
54
55        private float getScale(View view) {
56            lazyInit(view.getResources());
57            return sScaleFactor[mScaleIndex];
58        }
59
60        private void viewFocused(View view, boolean hasFocus) {
61            if (hasFocus) {
62                final float scale = getScale(view);
63                view.animate().scaleX(scale).scaleY(scale).setDuration(DURATION_MS);
64            } else {
65                view.animate().scaleX(1f).scaleY(1f).setDuration(DURATION_MS);
66            }
67            if (view instanceof ListRowCardWrapper) {
68                ListRowCardWrapper wrapper = (ListRowCardWrapper) view;
69                if (wrapper.mShadowNormal != null) {
70                    if (hasFocus) {
71                        wrapper.mShadowFocused.animate().alpha(1f)
72                                .setDuration(DURATION_MS).start();
73                        wrapper.mShadowNormal.animate().alpha(0f)
74                                .setDuration(DURATION_MS).start();
75                    } else {
76                        wrapper.mShadowFocused.animate().alpha(0f)
77                                .setDuration(DURATION_MS).start();
78                        wrapper.mShadowNormal.animate().alpha(1f)
79                                .setDuration(DURATION_MS).start();
80                    }
81                }
82            }
83        }
84
85        @Override
86        public void onItemFocused(View view, boolean hasFocus) {
87            viewFocused(view, hasFocus);
88        }
89    }
90
91    private static HeaderItemFocusHighlight sHeaderItemFocusHighlight =
92            new HeaderItemFocusHighlight();
93
94    private static ActionItemFocusHighlight sActionItemFocusHighlight =
95            new ActionItemFocusHighlight();
96
97    /**
98     * Setup the focus highlight behavior of a focused item in browse list row.
99     * @param adapter  adapter of the list row.
100     */
101    public static void setupBrowseItemFocusHighlight(ItemBridgeAdapter adapter, int zoomIndex) {
102        adapter.setFocusHighlight(new BrowseItemFocusHighlight(zoomIndex));
103    }
104
105    /**
106     * Setup the focus highlight behavior of a focused item in header list.
107     * @param adapter  adapter of the header list.
108     */
109    public static void setupHeaderItemFocusHighlight(ItemBridgeAdapter adapter) {
110        adapter.setFocusHighlight(sHeaderItemFocusHighlight);
111    }
112
113    /**
114     * Setup the focus highlight behavior of a focused item in an action list.
115     * @param adapter  adapter of the action list.
116     */
117    public static void setupActionItemFocusHighlight(ItemBridgeAdapter adapter) {
118        adapter.setFocusHighlight(sActionItemFocusHighlight);
119    }
120
121    private static class HeaderItemFocusHighlight implements FocusHighlight {
122        private boolean mInitialized;
123        private float mSelectScale;
124        private float mUnselectAlpha;
125        private int mDuration;
126
127        private void initializeDimensions(Resources res) {
128            if (!mInitialized) {
129                mSelectScale =
130                        Float.parseFloat(res.getString(R.dimen.lb_browse_header_select_scale));
131                mUnselectAlpha =
132                        Float.parseFloat(res.getString(R.dimen.lb_browse_header_unselect_alpha));
133                mDuration =
134                        Integer.parseInt(res.getString(R.dimen.lb_browse_header_select_duration));
135                mInitialized = true;
136            }
137        }
138
139        private void viewFocused(View view, boolean hasFocus) {
140            initializeDimensions(view.getResources());
141            if (hasFocus) {
142                view.animate().scaleX(mSelectScale).scaleY(mSelectScale)
143                        .alpha(1f)
144                        .setDuration(mDuration);
145            } else {
146                view.animate().scaleX(1f).scaleY(1f)
147                        .alpha(mUnselectAlpha)
148                        .setDuration(mDuration);
149            }
150        }
151
152        @Override
153        public void onItemFocused(View view, boolean hasFocus) {
154            viewFocused(view, hasFocus);
155        }
156    }
157
158    private static class ActionItemFocusHighlight implements FocusHighlight {
159        private boolean mInitialized;
160        private int mDuration;
161
162        private void initializeDimensions(Resources res) {
163            if (!mInitialized) {
164                mDuration = Integer.parseInt(res.getString(R.dimen.lb_details_overview_action_select_duration));
165            }
166        }
167
168        @Override
169        public void onItemFocused(View view, boolean hasFocus) {
170            initializeDimensions(view.getResources());
171            TransitionDrawable td = (TransitionDrawable) view.getBackground();
172            if (hasFocus) {
173                td.startTransition(mDuration);
174            } else {
175                td.reverseTransition(mDuration);
176            }
177        }
178    }
179}
180