VerticalGridFragment.java revision e7246ef136ed686d8caf339d4d1fd8e37b499c6a
1739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout/* 2739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Copyright (C) 2014 The Android Open Source Project 3739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * 4739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * in compliance with the License. You may obtain a copy of the License at 6739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * 7739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * http://www.apache.org/licenses/LICENSE-2.0 8739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * 9739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License 10739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * or implied. See the License for the specific language governing permissions and limitations under 12739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * the License. 13739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */ 14739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutpackage android.support.v17.leanback.app; 15739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 16739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.R; 175d00775a5d3ce3c1fc06c4de0945d1b8f03aadc4Dake Guimport android.support.v17.leanback.widget.BrowseFrameLayout; 18d586ba8825b418d9589436725bfdead30f0dc075Dake Guimport android.support.v17.leanback.widget.OnChildLaidOutListener; 19947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.OnItemViewClickedListener; 20947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.OnItemViewSelectedListener; 21947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.Presenter; 22e34cae48707e70442aca13e1b4ab55757292828dDake Guimport android.support.v17.leanback.widget.Row; 23947dbf076cd019e3c26217fbc7aa21e860d68044Dake Guimport android.support.v17.leanback.widget.RowPresenter; 24e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stoutimport android.support.v17.leanback.widget.TitleHelper; 25731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stoutimport android.support.v17.leanback.widget.TitleView; 26739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.VerticalGridPresenter; 27739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.support.v17.leanback.widget.ObjectAdapter; 28739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.os.Bundle; 2925aacd3f5896ec09053739cc731bdbab3a6f2b81Jerome Poichetimport android.util.Log; 30739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.LayoutInflater; 31739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.View; 32739e3805bf2785e6773aede5e2e1643f537305f9Craig Stoutimport android.view.ViewGroup; 33739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 34739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout/** 354c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn * A fragment for creating leanback vertical grids. 36739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * 374c0f3062b5edd9750351068f46e5270bb220091dTim Kilbourn * <p>Renders a vertical grid of objects given a {@link VerticalGridPresenter} and 38739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * an {@link ObjectAdapter}. 39739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */ 40e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stoutpublic class VerticalGridFragment extends BrandedFragment { 41739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout private static final String TAG = "VerticalGridFragment"; 42739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout private static boolean DEBUG = false; 43739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 44739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout private ObjectAdapter mAdapter; 45739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout private VerticalGridPresenter mGridPresenter; 46739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout private VerticalGridPresenter.ViewHolder mGridViewHolder; 47947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu private OnItemViewSelectedListener mOnItemViewSelectedListener; 48947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu private OnItemViewClickedListener mOnItemViewClickedListener; 49739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout private int mSelectedPosition = -1; 50739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 51dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout /** 52dfb60d0af5d49da05c584d74245c616263f26b65Craig Stout * Sets the grid presenter. 53739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */ 54739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public void setGridPresenter(VerticalGridPresenter gridPresenter) { 55739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout if (gridPresenter == null) { 56739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout throw new IllegalArgumentException("Grid presenter may not be null"); 57739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 58739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mGridPresenter = gridPresenter; 59d586ba8825b418d9589436725bfdead30f0dc075Dake Gu mGridPresenter.setOnItemViewSelectedListener(mViewSelectedListener); 60947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu if (mOnItemViewClickedListener != null) { 61947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener); 62947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu } 63739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 64739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 65739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout /** 66739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Returns the grid presenter. 67739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */ 68739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public VerticalGridPresenter getGridPresenter() { 69739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout return mGridPresenter; 70739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 71739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 72739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout /** 73739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Sets the object adapter for the fragment. 74739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */ 75739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public void setAdapter(ObjectAdapter adapter) { 76739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mAdapter = adapter; 77739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout updateAdapter(); 78739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 79739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 80739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout /** 81739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Returns the object adapter. 82739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */ 83739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public ObjectAdapter getAdapter() { 84739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout return mAdapter; 85739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 86739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 87d586ba8825b418d9589436725bfdead30f0dc075Dake Gu final private OnItemViewSelectedListener mViewSelectedListener = 88947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu new OnItemViewSelectedListener() { 89e34cae48707e70442aca13e1b4ab55757292828dDake Gu @Override 90947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 91947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu RowPresenter.ViewHolder rowViewHolder, Row row) { 92e34cae48707e70442aca13e1b4ab55757292828dDake Gu int position = mGridViewHolder.getGridView().getSelectedPosition(); 93d586ba8825b418d9589436725bfdead30f0dc075Dake Gu if (DEBUG) Log.v(TAG, "grid selected position " + position); 94d586ba8825b418d9589436725bfdead30f0dc075Dake Gu gridOnItemSelected(position); 95947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu if (mOnItemViewSelectedListener != null) { 96947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu mOnItemViewSelectedListener.onItemSelected(itemViewHolder, item, 97947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu rowViewHolder, row); 98947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu } 99e34cae48707e70442aca13e1b4ab55757292828dDake Gu } 100e34cae48707e70442aca13e1b4ab55757292828dDake Gu }; 101e34cae48707e70442aca13e1b4ab55757292828dDake Gu 102d586ba8825b418d9589436725bfdead30f0dc075Dake Gu final private OnChildLaidOutListener mChildLaidOutListener = 103d586ba8825b418d9589436725bfdead30f0dc075Dake Gu new OnChildLaidOutListener() { 104d586ba8825b418d9589436725bfdead30f0dc075Dake Gu @Override 105d586ba8825b418d9589436725bfdead30f0dc075Dake Gu public void onChildLaidOut(ViewGroup parent, View view, int position, long id) { 106d586ba8825b418d9589436725bfdead30f0dc075Dake Gu if (position == 0) { 107d586ba8825b418d9589436725bfdead30f0dc075Dake Gu showOrHideTitle(); 108d586ba8825b418d9589436725bfdead30f0dc075Dake Gu } 109d586ba8825b418d9589436725bfdead30f0dc075Dake Gu } 110d586ba8825b418d9589436725bfdead30f0dc075Dake Gu }; 111d586ba8825b418d9589436725bfdead30f0dc075Dake Gu 112739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout /** 113739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Sets an item selection listener. 114947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu */ 115947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 116947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu mOnItemViewSelectedListener = listener; 117947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu } 118947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu 119d586ba8825b418d9589436725bfdead30f0dc075Dake Gu private void gridOnItemSelected(int position) { 120e34cae48707e70442aca13e1b4ab55757292828dDake Gu if (position != mSelectedPosition) { 121e34cae48707e70442aca13e1b4ab55757292828dDake Gu mSelectedPosition = position; 122d586ba8825b418d9589436725bfdead30f0dc075Dake Gu showOrHideTitle(); 123d586ba8825b418d9589436725bfdead30f0dc075Dake Gu } 124d586ba8825b418d9589436725bfdead30f0dc075Dake Gu } 125d586ba8825b418d9589436725bfdead30f0dc075Dake Gu 126d586ba8825b418d9589436725bfdead30f0dc075Dake Gu private void showOrHideTitle() { 127d586ba8825b418d9589436725bfdead30f0dc075Dake Gu if (mGridViewHolder.getGridView().findViewHolderForAdapterPosition(mSelectedPosition) 128d586ba8825b418d9589436725bfdead30f0dc075Dake Gu == null) { 129d586ba8825b418d9589436725bfdead30f0dc075Dake Gu return; 130d586ba8825b418d9589436725bfdead30f0dc075Dake Gu } 131d586ba8825b418d9589436725bfdead30f0dc075Dake Gu if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(mSelectedPosition)) { 132e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout showTitle(true); 133e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout } else { 134e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout showTitle(false); 135e34cae48707e70442aca13e1b4ab55757292828dDake Gu } 136e34cae48707e70442aca13e1b4ab55757292828dDake Gu } 137739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 138739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout /** 139739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Sets an item clicked listener. 140947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu */ 141947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 142947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu mOnItemViewClickedListener = listener; 143947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu if (mGridPresenter != null) { 144947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu mGridPresenter.setOnItemViewClickedListener(mOnItemViewClickedListener); 145947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu } 146947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu } 147947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu 148947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu /** 149947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu * Returns the item clicked listener. 150947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu */ 151947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu public OnItemViewClickedListener getOnItemViewClickedListener() { 152947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu return mOnItemViewClickedListener; 153947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu } 154947dbf076cd019e3c26217fbc7aa21e860d68044Dake Gu 155739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout @Override 156739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public View onCreateView(LayoutInflater inflater, ViewGroup container, 157739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout Bundle savedInstanceState) { 158e34cae48707e70442aca13e1b4ab55757292828dDake Gu ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment, 159e34cae48707e70442aca13e1b4ab55757292828dDake Gu container, false); 160e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout setTitleView((TitleView) root.findViewById(R.id.browse_title_group)); 161731066a59e10ddc7bb6c95d0b91b3e0e11e10396Craig Stout return root; 1629020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout } 1639020c0aec57b4e8994d66b7cd1a89c225e9bfa11Craig Stout 164739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout @Override 165739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public void onViewCreated(View view, Bundle savedInstanceState) { 166e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout super.onViewCreated(view, savedInstanceState); 167739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock); 168739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock); 169739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout gridDock.addView(mGridViewHolder.view); 170d586ba8825b418d9589436725bfdead30f0dc075Dake Gu mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener); 171739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 172739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout updateAdapter(); 173739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 174739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 175e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout private void setupFocusSearchListener() { 176e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout BrowseFrameLayout browseFrameLayout = (BrowseFrameLayout) getView().findViewById( 177e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout R.id.grid_frame); 178e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout browseFrameLayout.setOnFocusSearchListener(getTitleHelper().getOnFocusSearchListener()); 179e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout } 180e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout 181739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout @Override 182739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public void onStart() { 183739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout super.onStart(); 184e7246ef136ed686d8caf339d4d1fd8e37b499c6aCraig Stout setupFocusSearchListener(); 185739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mGridViewHolder.getGridView().requestFocus(); 186739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 187739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 188739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout @Override 189739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public void onDestroyView() { 190739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout super.onDestroyView(); 191739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mGridViewHolder = null; 192739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 193739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 194739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout /** 195739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout * Sets the selected item position. 196739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout */ 197739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout public void setSelectedPosition(int position) { 198739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mSelectedPosition = position; 199739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout if(mGridViewHolder != null && mGridViewHolder.getGridView().getAdapter() != null) { 200739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mGridViewHolder.getGridView().setSelectedPositionSmooth(position); 201739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 202739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 203739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout 204739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout private void updateAdapter() { 205739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout if (mGridViewHolder != null) { 206739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mGridPresenter.onBindViewHolder(mGridViewHolder, mAdapter); 207739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout if (mSelectedPosition != -1) { 208739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout mGridViewHolder.getGridView().setSelectedPosition(mSelectedPosition); 209739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 210739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 211739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout } 212739e3805bf2785e6773aede5e2e1643f537305f9Craig Stout} 213