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.annotation.ColorInt; 17import android.support.v17.leanback.R; 18import android.support.v17.leanback.widget.BrowseFrameLayout; 19import android.support.v17.leanback.widget.OnChildLaidOutListener; 20import android.support.v17.leanback.widget.OnItemViewClickedListener; 21import android.support.v17.leanback.widget.OnItemViewSelectedListener; 22import android.support.v17.leanback.widget.Presenter; 23import android.support.v17.leanback.widget.Row; 24import android.support.v17.leanback.widget.RowPresenter; 25import android.support.v17.leanback.widget.TitleHelper; 26import android.support.v17.leanback.widget.TitleView; 27import android.support.v17.leanback.widget.VerticalGridPresenter; 28import android.support.v17.leanback.widget.ObjectAdapter; 29import android.os.Bundle; 30import android.util.Log; 31import android.view.LayoutInflater; 32import android.view.View; 33import android.view.ViewGroup; 34 35/** 36 * A fragment for creating leanback vertical grids. 37 * 38 * <p>Renders a vertical grid of objects given a {@link VerticalGridPresenter} and 39 * an {@link ObjectAdapter}. 40 */ 41public class VerticalGridFragment extends BrandedFragment { 42 private static final String TAG = "VerticalGridFragment"; 43 private static boolean DEBUG = false; 44 45 private ObjectAdapter mAdapter; 46 private VerticalGridPresenter mGridPresenter; 47 private VerticalGridPresenter.ViewHolder mGridViewHolder; 48 private OnItemViewSelectedListener mOnItemViewSelectedListener; 49 private OnItemViewClickedListener mOnItemViewClickedListener; 50 private int mSelectedPosition = -1; 51 52 /** 53 * Sets the grid presenter. 54 */ 55 public void setGridPresenter(VerticalGridPresenter gridPresenter) { 56 if (gridPresenter == null) { 57 throw new IllegalArgumentException("Grid presenter may not be null"); 58 } 59 mGridPresenter = gridPresenter; 60 mGridPresenter.setOnItemViewSelectedListener(mViewSelectedListener); 61 if (mOnItemViewClickedListener != null) { 62 mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener); 63 } 64 } 65 66 /** 67 * Returns the grid presenter. 68 */ 69 public VerticalGridPresenter getGridPresenter() { 70 return mGridPresenter; 71 } 72 73 /** 74 * Sets the object adapter for the fragment. 75 */ 76 public void setAdapter(ObjectAdapter adapter) { 77 mAdapter = adapter; 78 updateAdapter(); 79 } 80 81 /** 82 * Returns the object adapter. 83 */ 84 public ObjectAdapter getAdapter() { 85 return mAdapter; 86 } 87 88 final private OnItemViewSelectedListener mViewSelectedListener = 89 new OnItemViewSelectedListener() { 90 @Override 91 public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 92 RowPresenter.ViewHolder rowViewHolder, Row row) { 93 int position = mGridViewHolder.getGridView().getSelectedPosition(); 94 if (DEBUG) Log.v(TAG, "grid selected position " + position); 95 gridOnItemSelected(position); 96 if (mOnItemViewSelectedListener != null) { 97 mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item, 98 rowViewHolder, row); 99 } 100 } 101 }; 102 103 final private OnChildLaidOutListener mChildLaidOutListener = 104 new OnChildLaidOutListener() { 105 @Override 106 public void onChildLaidOut(ViewGroup parent, View view, int position, long id) { 107 if (position == 0) { 108 showOrHideTitle(); 109 } 110 } 111 }; 112 113 /** 114 * Sets an item selection listener. 115 */ 116 public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 117 mOnItemViewSelectedListener = listener; 118 } 119 120 private void gridOnItemSelected(int position) { 121 if (position != mSelectedPosition) { 122 mSelectedPosition = position; 123 showOrHideTitle(); 124 } 125 } 126 127 private void showOrHideTitle() { 128 if (mGridViewHolder.getGridView().findViewHolderForAdapterPosition(mSelectedPosition) 129 == null) { 130 return; 131 } 132 if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(mSelectedPosition)) { 133 showTitle(true); 134 } else { 135 showTitle(false); 136 } 137 } 138 139 /** 140 * Sets an item clicked listener. 141 */ 142 public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 143 mOnItemViewClickedListener = listener; 144 if (mGridPresenter != null) { 145 mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener); 146 } 147 } 148 149 /** 150 * Returns the item clicked listener. 151 */ 152 public OnItemViewClickedListener getOnItemViewClickedListener() { 153 return mOnItemViewClickedListener; 154 } 155 156 @Override 157 public View onCreateView(LayoutInflater inflater, ViewGroup container, 158 Bundle savedInstanceState) { 159 ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment, 160 container, false); 161 setTitleView((TitleView) root.findViewById(R.id.browse_title_group)); 162 return root; 163 } 164 165 @Override 166 public void onViewCreated(View view, Bundle savedInstanceState) { 167 super.onViewCreated(view, savedInstanceState); 168 ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock); 169 mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock); 170 gridDock.addView(mGridViewHolder.view); 171 mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener); 172 173 updateAdapter(); 174 } 175 176 private void setupFocusSearchListener() { 177 BrowseFrameLayout browseFrameLayout = (BrowseFrameLayout) getView().findViewById( 178 R.id.grid_frame); 179 browseFrameLayout.setOnFocusSearchListener(getTitleHelper().getOnFocusSearchListener()); 180 } 181 182 @Override 183 public void onStart() { 184 super.onStart(); 185 setupFocusSearchListener(); 186 mGridViewHolder.getGridView().requestFocus(); 187 } 188 189 @Override 190 public void onDestroyView() { 191 super.onDestroyView(); 192 mGridViewHolder = null; 193 } 194 195 /** 196 * Sets the selected item position. 197 */ 198 public void setSelectedPosition(int position) { 199 mSelectedPosition = position; 200 if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) { 201 mGridViewHolder.getGridView().setSelectedPositionSmooth(position); 202 } 203 } 204 205 private void updateAdapter() { 206 if (mGridViewHolder != null) { 207 mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter); 208 if (mSelectedPosition != -1) { 209 mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition); 210 } 211 } 212 } 213} 214