PlaybackControlsRowPresenter.java revision 6b2e5b5117f1b8dfafbd81b995bb423ab0297564
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.widget; 15 16import android.support.v17.leanback.R; 17import android.content.Context; 18import android.graphics.Color; 19import android.util.TypedValue; 20import android.view.LayoutInflater; 21import android.view.View; 22import android.view.ViewGroup; 23import android.view.ViewGroup.LayoutParams; 24import android.view.ViewGroup.MarginLayoutParams; 25import android.widget.ImageView; 26 27/** 28 * A PlaybackControlsRowPresenter renders a {@link PlaybackControlsRow} to display a 29 * series of playback control buttons. Typically this row will be the first row in a fragment 30 * such as the {@link android.support.v17.leanback.app.PlaybackOverlayFragment 31 * PlaybackControlsFragment}. 32 */ 33public class PlaybackControlsRowPresenter extends RowPresenter { 34 35 /** 36 * A ViewHolder for the PlaybackControlsRow. 37 */ 38 public class ViewHolder extends RowPresenter.ViewHolder { 39 public final Presenter.ViewHolder mDescriptionViewHolder; 40 final ViewGroup mCard; 41 final ImageView mImageView; 42 final ViewGroup mDescriptionDock; 43 final ViewGroup mControlsDock; 44 final ViewGroup mSecondaryControlsDock; 45 final View mSpacer; 46 int mCardHeight; 47 int mControlsDockMarginStart; 48 int mControlsDockMarginEnd; 49 PlaybackControlsPresenter.ViewHolder mControlsVh; 50 Presenter.ViewHolder mSecondaryControlsVh; 51 PlaybackControlsPresenter.BoundData mControlsBoundData = 52 new PlaybackControlsPresenter.BoundData(); 53 ControlBarPresenter.BoundData mSecondaryBoundData = new ControlBarPresenter.BoundData(); 54 final PlaybackControlsRow.OnPlaybackStateChangedListener mListener = 55 new PlaybackControlsRow.OnPlaybackStateChangedListener() { 56 @Override 57 public void onCurrentTimeChanged(int ms) { 58 mPlaybackControlsPresenter.setCurrentTime(mControlsVh, ms); 59 } 60 @Override 61 public void onBufferedProgressChanged(int ms) { 62 mPlaybackControlsPresenter.setSecondaryProgress(mControlsVh, ms); 63 } 64 }; 65 final OnItemViewSelectedListener mOnItemViewSelectedListener = 66 new OnItemViewSelectedListener() { 67 @Override 68 public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, 69 RowPresenter.ViewHolder rowViewHolder, Row row) { 70 if (getOnItemViewSelectedListener() != null) { 71 getOnItemViewSelectedListener().onItemSelected(itemViewHolder, item, 72 ViewHolder.this, getRow()); 73 } 74 } 75 }; 76 77 ViewHolder(View rootView, Presenter descriptionPresenter) { 78 super(rootView); 79 mCard = (ViewGroup) rootView.findViewById(R.id.controls_card); 80 mImageView = (ImageView) rootView.findViewById(R.id.image); 81 mDescriptionDock = (ViewGroup) rootView.findViewById(R.id.description_dock); 82 mControlsDock = (ViewGroup) rootView.findViewById(R.id.controls_dock); 83 mSecondaryControlsDock = 84 (ViewGroup) rootView.findViewById(R.id.secondary_controls_dock); 85 mSpacer = rootView.findViewById(R.id.spacer); 86 mDescriptionViewHolder = descriptionPresenter == null ? null : 87 descriptionPresenter.onCreateViewHolder(mDescriptionDock); 88 if (mDescriptionViewHolder != null) { 89 mDescriptionDock.addView(mDescriptionViewHolder.view); 90 } 91 } 92 93 Presenter getPresenter(Object item, boolean primary) { 94 ObjectAdapter adapter = primary ? 95 ((PlaybackControlsRow) getRow()).getPrimaryActionsAdapter() : 96 ((PlaybackControlsRow) getRow()).getSecondaryActionsAdapter(); 97 if (adapter.getPresenterSelector() instanceof ControlButtonPresenterSelector) { 98 ControlButtonPresenterSelector selector = 99 (ControlButtonPresenterSelector) adapter.getPresenterSelector(); 100 return primary ? selector.getPrimaryPresenter() : 101 selector.getSecondaryPresenter(); 102 } 103 return adapter.getPresenter(item); 104 } 105 } 106 107 private int mBackgroundColor = Color.TRANSPARENT; 108 private boolean mBackgroundColorSet; 109 private int mProgressColor = Color.TRANSPARENT; 110 private boolean mProgressColorSet; 111 private boolean mSecondaryActionsHidden; 112 private Presenter mDescriptionPresenter; 113 private PlaybackControlsPresenter mPlaybackControlsPresenter; 114 private ControlBarPresenter mSecondaryControlsPresenter; 115 116 /** 117 * Constructor for a PlaybackControlsRowPresenter. 118 * 119 * @param descriptionPresenter Presenter for displaying item details. 120 */ 121 public PlaybackControlsRowPresenter(Presenter descriptionPresenter) { 122 setHeaderPresenter(null); 123 setSelectEffectEnabled(false); 124 125 mDescriptionPresenter = descriptionPresenter; 126 mPlaybackControlsPresenter = new PlaybackControlsPresenter(R.layout.lb_playback_controls); 127 mSecondaryControlsPresenter = new ControlBarPresenter(R.layout.lb_control_bar); 128 } 129 130 /** 131 * Constructor for a PlaybackControlsRowPresenter. 132 */ 133 public PlaybackControlsRowPresenter() { 134 this(null); 135 } 136 137 /** 138 * Sets the listener for {@link Action} click events. 139 */ 140 public void setOnActionClickedListener(OnActionClickedListener listener) { 141 mPlaybackControlsPresenter.setOnActionClickedListener(listener); 142 mSecondaryControlsPresenter.setOnActionClickedListener(listener); 143 } 144 145 /** 146 * Gets the listener for {@link Action} click events. 147 */ 148 public OnActionClickedListener getOnActionClickedListener() { 149 return mPlaybackControlsPresenter.getOnActionClickedListener(); 150 } 151 152 /** 153 * Sets the background color. If not set, a default from the theme will be used. 154 */ 155 public void setBackgroundColor(int color) { 156 mBackgroundColor = color; 157 mBackgroundColorSet = true; 158 } 159 160 /** 161 * Returns the background color. If no background color was set, transparent 162 * is returned. 163 */ 164 public int getBackgroundColor() { 165 return mBackgroundColor; 166 } 167 168 /** 169 * Sets the primary color for the progress bar. If not set, a default from 170 * the theme will be used. 171 */ 172 public void setProgressColor(int color) { 173 mProgressColor = color; 174 mProgressColorSet = true; 175 } 176 177 /** 178 * Returns the primary color for the progress bar. If no color was set, transparent 179 * is returned. 180 */ 181 public int getProgressColor() { 182 return mProgressColor; 183 } 184 185 /** 186 * Sets the secondary actions to be hidden behind a "more actions" button. 187 * When "more actions" is selected, the primary actions are replaced with 188 * the secondary actions. 189 */ 190 public void setSecondaryActionsHidden(boolean hidden) { 191 mSecondaryActionsHidden = hidden; 192 } 193 194 /** 195 * Returns true if secondary actions are hidden. 196 */ 197 public boolean areSecondaryActionsHidden() { 198 return mSecondaryActionsHidden; 199 } 200 201 private int getDefaultBackgroundColor(Context context) { 202 TypedValue outValue = new TypedValue(); 203 context.getTheme().resolveAttribute(R.attr.defaultBrandColor, outValue, true); 204 return context.getResources().getColor(outValue.resourceId); 205 } 206 207 private int getDefaultProgressColor(Context context) { 208 TypedValue outValue = new TypedValue(); 209 context.getTheme().resolveAttribute(R.attr.playbackProgressPrimaryColor, outValue, true); 210 return context.getResources().getColor(outValue.resourceId); 211 } 212 213 @Override 214 protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { 215 View v = LayoutInflater.from(parent.getContext()) 216 .inflate(R.layout.lb_playback_controls_row, parent, false); 217 ViewHolder vh = new ViewHolder(v, mDescriptionPresenter); 218 initRow(vh); 219 return vh; 220 } 221 222 private void initRow(ViewHolder vh) { 223 vh.mCardHeight = vh.mCard.getLayoutParams().height; 224 225 MarginLayoutParams lp = (MarginLayoutParams) vh.mControlsDock.getLayoutParams(); 226 vh.mControlsDockMarginStart = lp.getMarginStart(); 227 vh.mControlsDockMarginEnd = lp.getMarginEnd(); 228 229 vh.mControlsVh = (PlaybackControlsPresenter.ViewHolder) 230 mPlaybackControlsPresenter.onCreateViewHolder(vh.mControlsDock); 231 mPlaybackControlsPresenter.setProgressColor(vh.mControlsVh, 232 mProgressColorSet ? mProgressColor : 233 getDefaultProgressColor(vh.mControlsDock.getContext())); 234 mPlaybackControlsPresenter.setOnItemViewSelectedListener(vh.mOnItemViewSelectedListener); 235 vh.mControlsDock.addView(vh.mControlsVh.view); 236 237 vh.mSecondaryControlsVh = 238 mSecondaryControlsPresenter.onCreateViewHolder(vh.mSecondaryControlsDock); 239 if (!mSecondaryActionsHidden) { 240 vh.mSecondaryControlsDock.addView(vh.mSecondaryControlsVh.view); 241 } 242 mSecondaryControlsPresenter.setOnItemViewSelectedListener(vh.mOnItemViewSelectedListener); 243 } 244 245 private void setBackground(View view) { 246 view.setBackgroundColor(mBackgroundColorSet ? 247 mBackgroundColor : getDefaultBackgroundColor(view.getContext())); 248 ShadowHelper.getInstance().setZ(view, 0f); 249 } 250 251 @Override 252 protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) { 253 super.onBindRowViewHolder(holder, item); 254 255 ViewHolder vh = (ViewHolder) holder; 256 PlaybackControlsRow row = (PlaybackControlsRow) vh.getRow(); 257 258 mPlaybackControlsPresenter.enableSecondaryActions(mSecondaryActionsHidden); 259 260 if (row.getItem() == null) { 261 LayoutParams lp = vh.mCard.getLayoutParams(); 262 lp.height = LayoutParams.WRAP_CONTENT; 263 vh.mCard.setLayoutParams(lp); 264 vh.mDescriptionDock.setVisibility(View.GONE); 265 vh.mSpacer.setVisibility(View.GONE); 266 } else { 267 LayoutParams lp = vh.mCard.getLayoutParams(); 268 lp.height = vh.mCardHeight; 269 vh.mCard.setLayoutParams(lp); 270 vh.mDescriptionDock.setVisibility(View.VISIBLE); 271 if (vh.mDescriptionViewHolder != null) { 272 mDescriptionPresenter.onBindViewHolder(vh.mDescriptionViewHolder, row.getItem()); 273 } 274 vh.mSpacer.setVisibility(View.VISIBLE); 275 } 276 277 MarginLayoutParams lp = (MarginLayoutParams) vh.mControlsDock.getLayoutParams(); 278 if (row.getImageDrawable() == null || row.getItem() == null) { 279 setBackground(vh.mControlsDock); 280 vh.mCard.setBackgroundColor(Color.TRANSPARENT); 281 lp.setMarginStart(0); 282 lp.setMarginEnd(0); 283 mPlaybackControlsPresenter.enableTimeMargins(vh.mControlsVh, true); 284 } else { 285 vh.mImageView.setImageDrawable(row.getImageDrawable()); 286 setBackground(vh.mCard); 287 vh.mControlsDock.setBackgroundColor(Color.TRANSPARENT); 288 lp.setMarginStart(vh.mControlsDockMarginStart); 289 lp.setMarginEnd(vh.mControlsDockMarginEnd); 290 mPlaybackControlsPresenter.enableTimeMargins(vh.mControlsVh, false); 291 } 292 vh.mControlsDock.setLayoutParams(lp); 293 294 vh.mControlsBoundData.adapter = row.getPrimaryActionsAdapter(); 295 vh.mControlsBoundData.secondaryActionsAdapter = row.getSecondaryActionsAdapter(); 296 vh.mControlsBoundData.presenter = vh.getPresenter( 297 row.getPrimaryActionsAdapter().get(0), true); 298 mPlaybackControlsPresenter.onBindViewHolder(vh.mControlsVh, vh.mControlsBoundData); 299 300 vh.mSecondaryBoundData.adapter = row.getSecondaryActionsAdapter(); 301 vh.mSecondaryBoundData.presenter = vh.getPresenter( 302 row.getSecondaryActionsAdapter().get(0), false); 303 mSecondaryControlsPresenter.onBindViewHolder(vh.mSecondaryControlsVh, 304 vh.mSecondaryBoundData); 305 306 mPlaybackControlsPresenter.setTotalTime(vh.mControlsVh, row.getTotalTime()); 307 mPlaybackControlsPresenter.setCurrentTime(vh.mControlsVh, row.getCurrentTime()); 308 mPlaybackControlsPresenter.setSecondaryProgress(vh.mControlsVh, row.getBufferedProgress()); 309 row.setOnPlaybackStateChangedListener(vh.mListener); 310 } 311 312 @Override 313 protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) { 314 ViewHolder vh = (ViewHolder) holder; 315 PlaybackControlsRow row = (PlaybackControlsRow) vh.getRow(); 316 317 if (vh.mDescriptionViewHolder != null) { 318 mDescriptionPresenter.onUnbindViewHolder(vh.mDescriptionViewHolder); 319 } 320 mPlaybackControlsPresenter.onUnbindViewHolder(vh.mControlsVh); 321 mSecondaryControlsPresenter.onUnbindViewHolder(vh.mSecondaryControlsVh); 322 row.setOnPlaybackStateChangedListener(null); 323 324 super.onUnbindRowViewHolder(holder); 325 } 326} 327