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 */ 14 package android.support.v17.leanback.app; 15 16 import android.support.v17.leanback.R; 17 import android.support.v17.leanback.widget.ObjectAdapter; 18 import android.support.v17.leanback.widget.OnItemClickedListener; 19 import android.support.v17.leanback.widget.OnItemSelectedListener; 20 import android.support.v17.leanback.widget.OnItemViewClickedListener; 21 import android.support.v17.leanback.widget.OnItemViewSelectedListener; 22 import android.support.v17.leanback.widget.Presenter; 23 import android.support.v17.leanback.widget.Row; 24 import android.support.v17.leanback.widget.RowPresenter; 25 import android.support.v17.leanback.widget.VerticalGridView; 26 import android.app.Fragment; 27 import android.os.Bundle; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 32 /** 33 * Wrapper fragment for leanback details screens. 34 */ 35 public class DetailsFragment extends BaseFragment { 36 private static final String TAG = "DetailsFragment"; 37 private static boolean DEBUG = false; 38 39 private class SetSelectionRunnable implements Runnable { 40 int mPosition; 41 boolean mSmooth = true; 42 @Override run()43 public void run() { 44 mRowsFragment.setSelectedPosition(mPosition, mSmooth); 45 } 46 } 47 48 private RowsFragment mRowsFragment; 49 50 private ObjectAdapter mAdapter; 51 private int mContainerListAlignTop; 52 private OnItemSelectedListener mExternalOnItemSelectedListener; 53 private OnItemClickedListener mOnItemClickedListener; 54 private OnItemViewSelectedListener mExternalOnItemViewSelectedListener; 55 private OnItemViewClickedListener mOnItemViewClickedListener; 56 private int mSelectedPosition = -1; 57 58 private Object mSceneAfterEntranceTransition; 59 60 private final SetSelectionRunnable mSetSelectionRunnable = new SetSelectionRunnable(); 61 62 /** 63 * Sets the list of rows for the fragment. 64 */ setAdapter(ObjectAdapter adapter)65 public void setAdapter(ObjectAdapter adapter) { 66 mAdapter = adapter; 67 if (mRowsFragment != null) { 68 mRowsFragment.setAdapter(adapter); 69 } 70 } 71 72 /** 73 * Returns the list of rows. 74 */ getAdapter()75 public ObjectAdapter getAdapter() { 76 return mAdapter; 77 } 78 79 /** 80 * Sets an item selection listener. 81 * @deprecated Use {@link #setOnItemViewSelectedListener(OnItemViewSelectedListener)} 82 */ setOnItemSelectedListener(OnItemSelectedListener listener)83 public void setOnItemSelectedListener(OnItemSelectedListener listener) { 84 mExternalOnItemSelectedListener = listener; 85 } 86 87 /** 88 * Sets an item Clicked listener. 89 * @deprecated Use {@link #setOnItemViewClickedListener(OnItemViewClickedListener)} 90 */ setOnItemClickedListener(OnItemClickedListener listener)91 public void setOnItemClickedListener(OnItemClickedListener listener) { 92 mOnItemClickedListener = listener; 93 if (mRowsFragment != null) { 94 mRowsFragment.setOnItemClickedListener(listener); 95 } 96 } 97 98 /** 99 * Sets an item selection listener. 100 */ setOnItemViewSelectedListener(OnItemViewSelectedListener listener)101 public void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) { 102 mExternalOnItemViewSelectedListener = listener; 103 } 104 105 /** 106 * Sets an item Clicked listener. 107 */ setOnItemViewClickedListener(OnItemViewClickedListener listener)108 public void setOnItemViewClickedListener(OnItemViewClickedListener listener) { 109 mOnItemViewClickedListener = listener; 110 if (mRowsFragment != null) { 111 mRowsFragment.setOnItemViewClickedListener(listener); 112 } 113 } 114 115 /** 116 * Returns the item Clicked listener. 117 * @deprecated Use {@link #getOnItemViewClickedListener()} 118 */ getOnItemClickedListener()119 public OnItemClickedListener getOnItemClickedListener() { 120 return mOnItemClickedListener; 121 } 122 123 /** 124 * Returns the item Clicked listener. 125 */ getOnItemViewClickedListener()126 public OnItemViewClickedListener getOnItemViewClickedListener() { 127 return mOnItemViewClickedListener; 128 } 129 130 @Override onCreate(Bundle savedInstanceState)131 public void onCreate(Bundle savedInstanceState) { 132 super.onCreate(savedInstanceState); 133 134 mContainerListAlignTop = 135 getResources().getDimensionPixelSize(R.dimen.lb_details_rows_align_top); 136 } 137 138 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)139 public View onCreateView(LayoutInflater inflater, ViewGroup container, 140 Bundle savedInstanceState) { 141 View view = inflater.inflate(R.layout.lb_details_fragment, container, false); 142 mRowsFragment = (RowsFragment) getChildFragmentManager().findFragmentById( 143 R.id.fragment_dock); 144 if (mRowsFragment == null) { 145 mRowsFragment = new RowsFragment(); 146 getChildFragmentManager().beginTransaction() 147 .replace(R.id.fragment_dock, mRowsFragment).commit(); 148 } 149 mRowsFragment.setAdapter(mAdapter); 150 mRowsFragment.setOnItemSelectedListener(mExternalOnItemSelectedListener); 151 mRowsFragment.setOnItemViewSelectedListener(mExternalOnItemViewSelectedListener); 152 mRowsFragment.setOnItemClickedListener(mOnItemClickedListener); 153 mRowsFragment.setOnItemViewClickedListener(mOnItemViewClickedListener); 154 mSceneAfterEntranceTransition = sTransitionHelper.createScene((ViewGroup) view, 155 new Runnable() { 156 @Override 157 public void run() { 158 mRowsFragment.setEntranceTransitionState(true); 159 } 160 }); 161 return view; 162 } 163 setVerticalGridViewLayout(VerticalGridView listview)164 void setVerticalGridViewLayout(VerticalGridView listview) { 165 // align the top edge of item to a fixed position 166 listview.setItemAlignmentOffset(0); 167 listview.setItemAlignmentOffsetPercent(VerticalGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED); 168 listview.setWindowAlignmentOffset(mContainerListAlignTop); 169 listview.setWindowAlignmentOffsetPercent(VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED); 170 listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE); 171 } 172 getVerticalGridView()173 VerticalGridView getVerticalGridView() { 174 return mRowsFragment == null ? null : mRowsFragment.getVerticalGridView(); 175 } 176 getRowsFragment()177 RowsFragment getRowsFragment() { 178 return mRowsFragment; 179 } 180 181 /** 182 * Setup dimensions that are only meaningful when the child Fragments are inside 183 * DetailsFragment. 184 */ setupChildFragmentLayout()185 private void setupChildFragmentLayout() { 186 setVerticalGridViewLayout(mRowsFragment.getVerticalGridView()); 187 } 188 189 /** 190 * Sets the selected row position with smooth animation. 191 */ setSelectedPosition(int position)192 public void setSelectedPosition(int position) { 193 setSelectedPosition(position, true); 194 } 195 196 /** 197 * Sets the selected row position. 198 */ setSelectedPosition(int position, boolean smooth)199 public void setSelectedPosition(int position, boolean smooth) { 200 mSetSelectionRunnable.mPosition = position; 201 mSetSelectionRunnable.mSmooth = smooth; 202 if (getView() != null && getView().getHandler() != null) { 203 getView().getHandler().post(mSetSelectionRunnable); 204 } 205 } 206 207 @Override onStart()208 public void onStart() { 209 super.onStart(); 210 setupChildFragmentLayout(); 211 mRowsFragment.getView().requestFocus(); 212 if (isEntranceTransitionEnabled()) { 213 // make sure recycler view animation is disabled 214 mRowsFragment.onTransitionStart(); 215 mRowsFragment.setEntranceTransitionState(false); 216 } 217 } 218 219 @Override createEntranceTransition()220 protected Object createEntranceTransition() { 221 return sTransitionHelper.loadTransition(getActivity(), 222 R.transition.lb_details_enter_transition); 223 } 224 225 @Override runEntranceTransition(Object entranceTransition)226 protected void runEntranceTransition(Object entranceTransition) { 227 sTransitionHelper.runTransition(mSceneAfterEntranceTransition, 228 entranceTransition); 229 } 230 231 @Override onEntranceTransitionEnd()232 protected void onEntranceTransitionEnd() { 233 mRowsFragment.onTransitionEnd(); 234 } 235 236 } 237