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