FocusHighlightHelper.java revision b55f0880c367c0b7e4132e7d954b60725e01e0b2
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 21import static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_NONE; 22import static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_SMALL; 23import static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_MEDIUM; 24import static android.support.v17.leanback.widget.FocusHighlight.ZOOM_FACTOR_LARGE; 25 26 27/** 28 * Setup the behavior how to highlight when a item gains focus. 29 */ 30public class FocusHighlightHelper { 31 32 static class BrowseItemFocusHighlight implements FocusHighlight { 33 private static final int DURATION_MS = 150; 34 35 private static float[] sScaleFactor = new float[4]; 36 37 private int mScaleIndex; 38 39 BrowseItemFocusHighlight(int zoomIndex) { 40 mScaleIndex = (zoomIndex >= 0 && zoomIndex < sScaleFactor.length) ? 41 zoomIndex : ZOOM_FACTOR_MEDIUM; 42 } 43 44 private void lazyInit(Resources resources) { 45 if (sScaleFactor[ZOOM_FACTOR_NONE] == 0f) { 46 sScaleFactor[ZOOM_FACTOR_NONE] = 1f; 47 sScaleFactor[ZOOM_FACTOR_SMALL] = 48 resources.getFraction(R.fraction.lb_focus_zoom_factor_small, 1, 1); 49 sScaleFactor[ZOOM_FACTOR_MEDIUM] = 50 resources.getFraction(R.fraction.lb_focus_zoom_factor_medium, 1, 1); 51 sScaleFactor[ZOOM_FACTOR_LARGE] = 52 resources.getFraction(R.fraction.lb_focus_zoom_factor_large, 1, 1); 53 } 54 } 55 56 private float getScale(View view) { 57 lazyInit(view.getResources()); 58 return sScaleFactor[mScaleIndex]; 59 } 60 61 private void viewFocused(View view, boolean hasFocus) { 62 view.setSelected(hasFocus); 63 if (hasFocus) { 64 final float scale = getScale(view); 65 view.animate().scaleX(scale).scaleY(scale).setDuration(DURATION_MS); 66 } else { 67 view.animate().scaleX(1f).scaleY(1f).setDuration(DURATION_MS); 68 } 69 if (view instanceof ListRowCardWrapper) { 70 ListRowCardWrapper wrapper = (ListRowCardWrapper) view; 71 if (wrapper.mShadowNormal != null) { 72 if (hasFocus) { 73 wrapper.mShadowFocused.animate().alpha(1f) 74 .setDuration(DURATION_MS).start(); 75 wrapper.mShadowNormal.animate().alpha(0f) 76 .setDuration(DURATION_MS).start(); 77 } else { 78 wrapper.mShadowFocused.animate().alpha(0f) 79 .setDuration(DURATION_MS).start(); 80 wrapper.mShadowNormal.animate().alpha(1f) 81 .setDuration(DURATION_MS).start(); 82 } 83 } 84 } 85 } 86 87 @Override 88 public void onItemFocused(View view, boolean hasFocus) { 89 viewFocused(view, hasFocus); 90 } 91 } 92 93 private static HeaderItemFocusHighlight sHeaderItemFocusHighlight = 94 new HeaderItemFocusHighlight(); 95 96 private static ActionItemFocusHighlight sActionItemFocusHighlight = 97 new ActionItemFocusHighlight(); 98 99 /** 100 * Setup the focus highlight behavior of a focused item in browse list row. 101 * @param adapter adapter of the list row. 102 */ 103 public static void setupBrowseItemFocusHighlight(ItemBridgeAdapter adapter, int zoomIndex) { 104 adapter.setFocusHighlight(new BrowseItemFocusHighlight(zoomIndex)); 105 } 106 107 /** 108 * Setup the focus highlight behavior of a focused item in header list. 109 * @param adapter adapter of the header list. 110 */ 111 public static void setupHeaderItemFocusHighlight(ItemBridgeAdapter adapter) { 112 adapter.setFocusHighlight(sHeaderItemFocusHighlight); 113 } 114 115 /** 116 * Setup the focus highlight behavior of a focused item in an action list. 117 * @param adapter adapter of the action list. 118 */ 119 public static void setupActionItemFocusHighlight(ItemBridgeAdapter adapter) { 120 adapter.setFocusHighlight(sActionItemFocusHighlight); 121 } 122 123 private static class HeaderItemFocusHighlight implements FocusHighlight { 124 private boolean mInitialized; 125 private float mSelectScale; 126 private float mUnselectAlpha; 127 private int mDuration; 128 129 private void initializeDimensions(Resources res) { 130 if (!mInitialized) { 131 mSelectScale = 132 Float.parseFloat(res.getString(R.dimen.lb_browse_header_select_scale)); 133 mUnselectAlpha = 134 Float.parseFloat(res.getString(R.dimen.lb_browse_header_unselect_alpha)); 135 mDuration = 136 Integer.parseInt(res.getString(R.dimen.lb_browse_header_select_duration)); 137 mInitialized = true; 138 } 139 } 140 141 private void viewFocused(View view, boolean hasFocus) { 142 initializeDimensions(view.getResources()); 143 if (hasFocus) { 144 view.animate().scaleX(mSelectScale).scaleY(mSelectScale) 145 .alpha(1f) 146 .setDuration(mDuration); 147 } else { 148 view.animate().scaleX(1f).scaleY(1f) 149 .alpha(mUnselectAlpha) 150 .setDuration(mDuration); 151 } 152 } 153 154 @Override 155 public void onItemFocused(View view, boolean hasFocus) { 156 viewFocused(view, hasFocus); 157 } 158 } 159 160 private static class ActionItemFocusHighlight implements FocusHighlight { 161 private boolean mInitialized; 162 private int mDuration; 163 164 private void initializeDimensions(Resources res) { 165 if (!mInitialized) { 166 mDuration = Integer.parseInt(res.getString(R.dimen.lb_details_overview_action_select_duration)); 167 } 168 } 169 170 @Override 171 public void onItemFocused(View view, boolean hasFocus) { 172 initializeDimensions(view.getResources()); 173 TransitionDrawable td = (TransitionDrawable) view.getBackground(); 174 if (hasFocus) { 175 td.startTransition(mDuration); 176 } else { 177 td.reverseTransition(mDuration); 178 } 179 } 180 } 181} 182