VerticalGridFragment.java revision dfb60d0af5d49da05c584d74245c616263f26b65
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.app; 15 16import android.support.v17.leanback.R; 17import android.support.v17.leanback.widget.Row; 18import android.support.v17.leanback.widget.VerticalGridPresenter; 19import android.support.v17.leanback.widget.ObjectAdapter; 20import android.support.v17.leanback.widget.OnItemClickedListener; 21import android.support.v17.leanback.widget.OnItemSelectedListener; 22import android.support.v17.leanback.widget.SearchOrbView; 23import android.app.Fragment; 24import android.graphics.drawable.Drawable; 25import android.os.Bundle; 26import android.util.Log; 27import android.view.LayoutInflater; 28import android.view.View; 29import android.view.ViewGroup; 30import android.widget.ImageView; 31import android.widget.TextView; 32 33/** 34 * Leanback fragment for a vertical grid. 35 * 36 * Renders a vertical grid of objects given a {@link VerticalGridPresenter} and 37 * an {@link ObjectAdapter}. 38 */ 39public class VerticalGridFragment extends Fragment { 40 private static final String TAG = "VerticalGridFragment"; 41 private static boolean DEBUG = false; 42 43 // TODO: remove Params 44 private Params mParams; 45 46 private String mTitle; 47 private Drawable mBadgeDrawable; 48 private ObjectAdapter mAdapter; 49 private VerticalGridPresenter mGridPresenter; 50 private VerticalGridPresenter.ViewHolder mGridViewHolder; 51 private OnItemSelectedListener mOnItemSelectedListener; 52 private OnItemClickedListener mOnItemClickedListener; 53 private View.OnClickListener mExternalOnSearchClickedListener; 54 private int mSelectedPosition = -1; 55 56 private ImageView mBadgeView; 57 private TextView mTitleView; 58 private ViewGroup mBrowseTitle; 59 private SearchOrbView mSearchOrbView; 60 private boolean mShowingTitle = true; 61 62 // transition related 63 private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance(); 64 private Object mTitleTransition; 65 private Object mSceneWithTitle; 66 private Object mSceneWithoutTitle; 67 68 @Deprecated 69 public static class Params { 70 private String mTitle; 71 private Drawable mBadgeDrawable; 72 73 /** 74 * Sets the badge image. 75 */ 76 public void setBadgeImage(Drawable drawable) { 77 mBadgeDrawable = drawable; 78 } 79 80 /** 81 * Returns the badge image. 82 */ 83 public Drawable getBadgeImage() { 84 return mBadgeDrawable; 85 } 86 87 /** 88 * Sets a title for the browse fragment. 89 */ 90 public void setTitle(String title) { 91 mTitle = title; 92 } 93 94 /** 95 * Returns the title for the browse fragment. 96 */ 97 public String getTitle() { 98 return mTitle; 99 } 100 } 101 102 /** 103 * Set fragment parameters. 104 * @deprecated Use methods on the fragment directly. 105 */ 106 @Deprecated 107 public void setParams(Params params) { 108 mParams = params; 109 setBadgeDrawable(mParams.mBadgeDrawable); 110 setTitle(mParams.mTitle); 111 } 112 113 /** 114 * Returns fragment parameters. 115 * @deprecated Use methods on the fragment directly. 116 */ 117 @Deprecated 118 public Params getParams() { 119 return mParams; 120 } 121 122 /** 123 * Sets the badge drawable displayed in the title area. 124 */ 125 public void setBadgeDrawable(Drawable drawable) { 126 if (drawable != mBadgeDrawable) { 127 mBadgeDrawable = drawable; 128 setBadgeViewImage(); 129 } 130 } 131 132 /** 133 * Returns the badge drawable. 134 */ 135 public Drawable getBadgeDrawable() { 136 return mBadgeDrawable; 137 } 138 139 /** 140 * Sets a title for the fragment. 141 */ 142 public void setTitle(String title) { 143 mTitle = title; 144 if (mTitleView != null) { 145 mTitleView.setText(mTitle); 146 } 147 } 148 149 /** 150 * Returns the title for the fragment. 151 */ 152 public String getTitle() { 153 return mTitle; 154 } 155 156 /** 157 * Sets the grid presenter. 158 */ 159 public void setGridPresenter(VerticalGridPresenter gridPresenter) { 160 if (gridPresenter == null) { 161 throw new IllegalArgumentException("Grid presenter may not be null"); 162 } 163 mGridPresenter = gridPresenter; 164 mGridPresenter.setOnItemSelectedListener(mRowSelectedListener); 165 if (mOnItemClickedListener != null) { 166 mGridPresenter.setOnItemClickedListener(mOnItemClickedListener); 167 } 168 } 169 170 /** 171 * Returns the grid presenter. 172 */ 173 public VerticalGridPresenter getGridPresenter() { 174 return mGridPresenter; 175 } 176 177 /** 178 * Sets the object adapter for the fragment. 179 */ 180 public void setAdapter(ObjectAdapter adapter) { 181 mAdapter = adapter; 182 updateAdapter(); 183 } 184 185 /** 186 * Returns the object adapter. 187 */ 188 public ObjectAdapter getAdapter() { 189 return mAdapter; 190 } 191 192 final private OnItemSelectedListener mRowSelectedListener = new OnItemSelectedListener() { 193 @Override 194 public void onItemSelected(Object item, Row row) { 195 int position = mGridViewHolder.getGridView().getSelectedPosition(); 196 if (DEBUG) Log.v(TAG, "row selected position " + position); 197 onRowSelected(position); 198 if (mOnItemSelectedListener != null) { 199 mOnItemSelectedListener.onItemSelected(item, row); 200 } 201 } 202 }; 203 204 /** 205 * Sets an item selection listener. 206 */ 207 public void setOnItemSelectedListener(OnItemSelectedListener listener) { 208 mOnItemSelectedListener = listener; 209 } 210 211 private void onRowSelected(int position) { 212 if (position != mSelectedPosition) { 213 if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(position)) { 214 // if has no sibling in front of it, show title 215 if (!mShowingTitle) { 216 sTransitionHelper.runTransition(mSceneWithTitle, mTitleTransition); 217 mShowingTitle = true; 218 } 219 } else if (mShowingTitle) { 220 sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleTransition); 221 mShowingTitle = false; 222 } 223 mSelectedPosition = position; 224 } 225 } 226 227 /** 228 * Sets an item clicked listener. 229 */ 230 public void setOnItemClickedListener(OnItemClickedListener listener) { 231 mOnItemClickedListener = listener; 232 if (mGridPresenter != null) { 233 mGridPresenter.setOnItemClickedListener(mOnItemClickedListener); 234 } 235 } 236 237 /** 238 * Returns the item clicked listener. 239 */ 240 public OnItemClickedListener getOnItemClickedListener() { 241 return mOnItemClickedListener; 242 } 243 244 /** 245 * Sets a click listener for the search affordance. 246 * 247 * The presence of a listener will change the visibility of the search affordance in the 248 * title area. When set to non-null the title area will contain a call to search action. 249 * 250 * The listener onClick method will be invoked when the user click on the search action. 251 * 252 * @param listener The listener. 253 */ 254 public void setOnSearchClickedListener(View.OnClickListener listener) { 255 mExternalOnSearchClickedListener = listener; 256 if (mSearchOrbView != null) { 257 mSearchOrbView.setOnOrbClickedListener(listener); 258 } 259 } 260 261 private void setBadgeViewImage() { 262 if (mBadgeView == null) { 263 return; 264 } 265 mBadgeView.setImageDrawable(mBadgeDrawable); 266 if (mBadgeDrawable != null) { 267 mBadgeView.setVisibility(View.VISIBLE); 268 mTitleView.setVisibility(View.GONE); 269 } else { 270 mBadgeView.setVisibility(View.GONE); 271 mTitleView.setVisibility(View.VISIBLE); 272 } 273 } 274 275 @Override 276 public View onCreateView(LayoutInflater inflater, ViewGroup container, 277 Bundle savedInstanceState) { 278 ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment, 279 container, false); 280 281 mBrowseTitle = (ViewGroup) root.findViewById(R.id.browse_title_group); 282 mBadgeView = (ImageView) mBrowseTitle.findViewById(R.id.browse_badge); 283 mTitleView = (TextView) mBrowseTitle.findViewById(R.id.browse_title); 284 mSearchOrbView = (SearchOrbView) mBrowseTitle.findViewById(R.id.browse_orb); 285 if (mExternalOnSearchClickedListener != null) { 286 mSearchOrbView.setOnOrbClickedListener(mExternalOnSearchClickedListener); 287 } 288 289 setBadgeViewImage(); 290 mTitleView.setText(mTitle); 291 292 mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() { 293 @Override 294 public void run() { 295 mBrowseTitle.setVisibility(View.VISIBLE); 296 } 297 }); 298 mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() { 299 @Override 300 public void run() { 301 mBrowseTitle.setVisibility(View.GONE); 302 } 303 }); 304 mTitleTransition = sTransitionHelper.createTransitionSet(false); 305 Object fade = sTransitionHelper.createFadeTransition( 306 TransitionHelper.FADE_IN | TransitionHelper.FADE_OUT); 307 Object changeBounds = sTransitionHelper.createChangeBounds(false); 308 sTransitionHelper.addTransition(mTitleTransition, fade); 309 sTransitionHelper.addTransition(mTitleTransition, changeBounds); 310 sTransitionHelper.excludeChildren(mTitleTransition, R.id.browse_grid_dock, true); 311 return root; 312 } 313 314 @Override 315 public void onViewCreated(View view, Bundle savedInstanceState) { 316 ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock); 317 mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock); 318 gridDock.addView(mGridViewHolder.view); 319 320 updateAdapter(); 321 } 322 323 @Override 324 public void onStart() { 325 super.onStart(); 326 mGridViewHolder.getGridView().requestFocus(); 327 } 328 329 @Override 330 public void onDestroyView() { 331 super.onDestroyView(); 332 mGridViewHolder = null; 333 } 334 335 /** 336 * Sets the selected item position. 337 */ 338 public void setSelectedPosition(int position) { 339 mSelectedPosition = position; 340 if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) { 341 mGridViewHolder.getGridView().setSelectedPositionSmooth(position); 342 } 343 } 344 345 private void updateAdapter() { 346 if (mGridViewHolder != null) { 347 mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter); 348 if (mSelectedPosition != -1) { 349 mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition); 350 } 351 } 352 } 353} 354