VerticalGridSupportFragment.java revision 4a10f1eb5c4283cfeef34cd71b84173f5ab3eefb
1/* This file is auto-generated from VerticalGridFragment.java. DO NOT MODIFY. */ 2 3/* 4 * Copyright (C) 2014 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 7 * in compliance with the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the License 12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 * or implied. See the License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16package android.support.v17.leanback.app; 17 18import android.support.v17.leanback.R; 19import android.support.v17.leanback.transition.TransitionHelper; 20import android.support.v17.leanback.widget.BrowseFrameLayout; 21import android.support.v17.leanback.widget.OnItemViewClickedListener; 22import android.support.v17.leanback.widget.OnItemViewSelectedListener; 23import android.support.v17.leanback.widget.Presenter; 24import android.support.v17.leanback.widget.Row; 25import android.support.v17.leanback.widget.RowPresenter; 26import android.support.v17.leanback.widget.TitleView; 27import android.support.v17.leanback.widget.VerticalGridPresenter; 28import android.support.v17.leanback.widget.ObjectAdapter; 29import android.support.v17.leanback.widget.OnItemClickedListener; 30import android.support.v17.leanback.widget.OnItemSelectedListener; 31import android.support.v17.leanback.widget.SearchOrbView; 32import android.support.v4.view.ViewCompat; 33import android.support.v4.app.Fragment; 34import android.graphics.drawable.Drawable; 35import android.os.Bundle; 36import android.util.Log; 37import android.view.LayoutInflater; 38import android.view.View; 39import android.view.ViewGroup; 40import android.view.ViewGroup.MarginLayoutParams; 41import android.widget.ImageView; 42import android.widget.TextView; 43 44/** 45 * A fragment for creating leanback vertical grids. 46 * 47 * <p>Renders a vertical grid of objects given a {@link VerticalGridPresenter} and 48 * an {@link ObjectAdapter}. 49 */ 50public class VerticalGridSupportFragment extends Fragment { 51 private static final String TAG = "VerticalGridSupportFragment"; 52 private static boolean DEBUG = false; 53 54 private BrowseFrameLayout mBrowseFrame; 55 private String mTitle; 56 private Drawable mBadgeDrawable; 57 private ObjectAdapter mAdapter; 58 private VerticalGridPresenter mGridPresenter; 59 private VerticalGridPresenter.ViewHolder mGridViewHolder; 60 private OnItemSelectedListener mOnItemSelectedListener; 61 private OnItemClickedListener mOnItemClickedListener; 62 private OnItemViewSelectedListener mOnItemViewSelectedListener; 63 private OnItemViewClickedListener mOnItemViewClickedListener; 64 private View.OnClickListener mExternalOnSearchClickedListener; 65 private int mSelectedPosition = -1; 66 67 private TitleView mTitleView; 68 private SearchOrbView.Colors mSearchAffordanceColors; 69 private boolean mSearchAffordanceColorSet; 70 private boolean mShowingTitle = true; 71 72 // transition related 73 private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance(); 74 private Object mTitleUpTransition; 75 private Object mTitleDownTransition; 76 private Object mSceneWithTitle; 77 private Object mSceneWithoutTitle; 78 79 /** 80 * Sets the badge drawable displayed in the title area. 81 */ 82 public void setBadgeDrawable(Drawable drawable) { 83 if (drawable != mBadgeDrawable) { 84 mBadgeDrawable = drawable; 85 if (mTitleView != null) { 86 mTitleView.setBadgeDrawable(drawable); 87 } 88 } 89 } 90 91 /** 92 * Returns the badge drawable. 93 */ 94 public Drawable getBadgeDrawable() { 95 return mBadgeDrawable; 96 } 97 98 /** 99 * Sets a title for the fragment. 100 */ 101 public void setTitle(String title) { 102 mTitle = title; 103 if (mTitleView != null) { 104 mTitleView.setTitle(mTitle); 105 } 106 } 107 108 /** 109 * Returns the title for the fragment. 110 */ 111 public String getTitle() { 112 return mTitle; 113 } 114 115 /** 116 * Sets the grid presenter. 117 */ 118 public void setGridPresenter(VerticalGridPresenter gridPresenter) { 119 if (gridPresenter == null) { 120 throw new IllegalArgumentException("Grid presenter may not be null"); 121 } 122 mGridPresenter = gridPresenter; 123 mGridPresenter.setOnItemViewSelectedListener(mRowSelectedListener); 124 if (mOnItemViewClickedListener != null) { 125 mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener); 126 } 127 if (mOnItemClickedListener != null) { 128 mGridPresenter.setOnItemClickedListener(mOnItemClickedListener); 129 } 130 } 131 132 /** 133 * Returns the grid presenter. 134 */ 135 public VerticalGridPresenter getGridPresenter() { 136 return mGridPresenter; 137 } 138 139 /** 140 * Sets the object adapter for the fragment. 141 */ 142 public void setAdapter(ObjectAdapter adapter) { 143 mAdapter = adapter; 144 updateAdapter(); 145 } 146 147 /** 148 * Returns the object adapter. 149 */ 150 public ObjectAdapter getAdapter() { 151 return mAdapter; 152 } 153 154 final private OnItemViewSelectedListener mRowSelectedListener = 155 new OnItemViewSelectedListener() { 156 @Override 157 public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 158 RowPresenter.ViewHolder rowViewHolder, Row row) { 159 int position = mGridViewHolder.getGridView().getSelectedPosition(); 160 if (DEBUG) Log.v(TAG, "row selected position " + position); 161 onRowSelected(position); 162 if (mOnItemSelectedListener != null) { 163 mOnItemSelectedListener.onItemSelected(item, row); 164 } 165 if (mOnItemViewSelectedListener != null) { 166 mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item, 167 rowViewHolder, row); 168 } 169 } 170 }; 171 172 /** 173 * Sets an item selection listener. 174 * @deprecated Use {@link #setOnItemViewSelectedListener(OnItemViewSelectedListener)} 175 */ 176 public void setOnItemSelectedListener(OnItemSelectedListener listener) { 177 mOnItemSelectedListener = listener; 178 } 179 180 /** 181 * Sets an item selection listener. 182 */ 183 public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 184 mOnItemViewSelectedListener = listener; 185 } 186 187 private void onRowSelected(int position) { 188 if (position != mSelectedPosition) { 189 if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(position)) { 190 // if has no sibling in front of it, show title 191 if (!mShowingTitle) { 192 sTransitionHelper.runTransition(mSceneWithTitle, mTitleDownTransition); 193 mShowingTitle = true; 194 } 195 } else if (mShowingTitle) { 196 sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleUpTransition); 197 mShowingTitle = false; 198 } 199 mSelectedPosition = position; 200 } 201 } 202 203 /** 204 * Sets an item clicked listener. 205 * @deprecated Use {@link #setOnItemViewClickedListener(OnItemViewClickedListener)} 206 */ 207 public void setOnItemClickedListener(OnItemClickedListener listener) { 208 mOnItemClickedListener = listener; 209 if (mGridPresenter != null) { 210 mGridPresenter.setOnItemClickedListener(mOnItemClickedListener); 211 } 212 } 213 214 /** 215 * Returns the item clicked listener. 216 * @deprecated Use {@link #getOnItemViewClickedListener()} 217 */ 218 public OnItemClickedListener getOnItemClickedListener() { 219 return mOnItemClickedListener; 220 } 221 222 /** 223 * Sets an item clicked listener. 224 */ 225 public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 226 mOnItemViewClickedListener = listener; 227 if (mGridPresenter != null) { 228 mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener); 229 } 230 } 231 232 /** 233 * Returns the item clicked listener. 234 */ 235 public OnItemViewClickedListener getOnItemViewClickedListener() { 236 return mOnItemViewClickedListener; 237 } 238 239 /** 240 * Sets a click listener for the search affordance. 241 * 242 * <p>The presence of a listener will change the visibility of the search 243 * affordance in the title area. When set to non-null, the title area will 244 * contain a call to search action. 245 * 246 * <p>The listener's onClick method will be invoked when the user clicks on 247 * the search action. 248 * 249 * @param listener The listener to invoke when the search affordance is 250 * clicked, or null to hide the search affordance. 251 */ 252 public void setOnSearchClickedListener(View.OnClickListener listener) { 253 mExternalOnSearchClickedListener = listener; 254 if (mTitleView != null) { 255 mTitleView.setOnSearchClickedListener(listener); 256 } 257 } 258 259 /** 260 * Sets the {@link SearchOrbView.Colors} used to draw the search affordance. 261 */ 262 public void setSearchAffordanceColors(SearchOrbView.Colors colors) { 263 mSearchAffordanceColors = colors; 264 mSearchAffordanceColorSet = true; 265 if (mTitleView != null) { 266 mTitleView.setSearchAffordanceColors(mSearchAffordanceColors); 267 } 268 } 269 270 /** 271 * Returns the {@link SearchOrbView.Colors} used to draw the search affordance. 272 */ 273 public SearchOrbView.Colors getSearchAffordanceColors() { 274 if (mSearchAffordanceColorSet) { 275 return mSearchAffordanceColors; 276 } 277 if (mTitleView == null) { 278 throw new IllegalStateException("Fragment views not yet created"); 279 } 280 return mTitleView.getSearchAffordanceColors(); 281 } 282 283 /** 284 * Sets the color used to draw the search affordance. 285 * A default brighter color will be set by the framework. 286 * 287 * @param color The color to use for the search affordance. 288 */ 289 public void setSearchAffordanceColor(int color) { 290 setSearchAffordanceColors(new SearchOrbView.Colors(color)); 291 } 292 293 /** 294 * Returns the color used to draw the search affordance. 295 */ 296 public int getSearchAffordanceColor() { 297 return getSearchAffordanceColors().color; 298 } 299 300 private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener = 301 new BrowseFrameLayout.OnFocusSearchListener() { 302 @Override 303 public View onFocusSearch(View focused, int direction) { 304 if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction); 305 306 final View searchOrbView = mTitleView.getSearchAffordanceView(); 307 final boolean isRtl = ViewCompat.getLayoutDirection(focused) == 308 View.LAYOUT_DIRECTION_RTL; 309 final int forward = isRtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT; 310 if (focused == searchOrbView && ( 311 direction == View.FOCUS_DOWN || direction == forward)) { 312 return mGridViewHolder.view; 313 314 } else if (focused != searchOrbView && searchOrbView.getVisibility() == View.VISIBLE 315 && direction == View.FOCUS_UP) { 316 return searchOrbView; 317 318 } else { 319 return null; 320 } 321 } 322 }; 323 324 @Override 325 public View onCreateView(LayoutInflater inflater, ViewGroup container, 326 Bundle savedInstanceState) { 327 ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment, 328 container, false); 329 330 mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame); 331 mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener); 332 333 mTitleView = (TitleView) root.findViewById(R.id.browse_title_group); 334 mTitleView.setBadgeDrawable(mBadgeDrawable); 335 mTitleView.setTitle(mTitle); 336 if (mSearchAffordanceColorSet) { 337 mTitleView.setSearchAffordanceColors(mSearchAffordanceColors); 338 } 339 if (mExternalOnSearchClickedListener != null) { 340 mTitleView.setOnSearchClickedListener(mExternalOnSearchClickedListener); 341 } 342 343 mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() { 344 @Override 345 public void run() { 346 mTitleView.setVisibility(View.VISIBLE); 347 } 348 }); 349 mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() { 350 @Override 351 public void run() { 352 mTitleView.setVisibility(View.INVISIBLE); 353 } 354 }); 355 mTitleUpTransition = TitleTransitionHelper.createTransitionTitleUp(sTransitionHelper); 356 mTitleDownTransition = TitleTransitionHelper.createTransitionTitleDown(sTransitionHelper); 357 sTransitionHelper.excludeChildren(mTitleUpTransition, R.id.browse_grid_dock, true); 358 sTransitionHelper.excludeChildren(mTitleDownTransition, R.id.browse_grid_dock, true); 359 360 return root; 361 } 362 363 @Override 364 public void onViewCreated(View view, Bundle savedInstanceState) { 365 ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock); 366 mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock); 367 gridDock.addView(mGridViewHolder.view); 368 369 updateAdapter(); 370 } 371 372 @Override 373 public void onStart() { 374 super.onStart(); 375 mGridViewHolder.getGridView().requestFocus(); 376 } 377 378 @Override 379 public void onPause() { 380 mTitleView.enableAnimation(false); 381 super.onPause(); 382 } 383 384 @Override 385 public void onResume() { 386 super.onResume(); 387 mTitleView.enableAnimation(true); 388 } 389 390 @Override 391 public void onDestroyView() { 392 super.onDestroyView(); 393 mGridViewHolder = null; 394 } 395 396 /** 397 * Sets the selected item position. 398 */ 399 public void setSelectedPosition(int position) { 400 mSelectedPosition = position; 401 if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) { 402 mGridViewHolder.getGridView().setSelectedPositionSmooth(position); 403 } 404 } 405 406 private void updateAdapter() { 407 if (mGridViewHolder != null) { 408 mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter); 409 if (mSelectedPosition != -1) { 410 mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition); 411 } 412 } 413 } 414} 415