Fields Summary |
---|
public static final int | ACTION_CUSTOM_LEFT_FIRSTThe adapter key for the first custom control on the right side
of the predefined primary controls. |
public static final int | ACTION_SKIP_TO_PREVIOUSThe adapter key for the skip to previous control. |
public static final int | ACTION_REWINDThe adapter key for the rewind control. |
public static final int | ACTION_PLAY_PAUSEThe adapter key for the play/pause control. |
public static final int | ACTION_FAST_FORWARDThe adapter key for the fast forward control. |
public static final int | ACTION_SKIP_TO_NEXTThe adapter key for the skip to next control. |
public static final int | ACTION_CUSTOM_RIGHT_FIRSTThe adapter key for the first custom control on the right side
of the predefined primary controls. |
public static final int | PLAYBACK_SPEED_INVALIDInvalid playback speed. |
public static final int | PLAYBACK_SPEED_PAUSEDSpeed representing playback state that is paused. |
public static final int | PLAYBACK_SPEED_NORMALSpeed representing playback state that is playing normally. |
public static final int | PLAYBACK_SPEED_FAST_L0The initial (level 0) fast forward playback speed.
The negative of this value is for rewind at the same speed. |
public static final int | PLAYBACK_SPEED_FAST_L1The level 1 fast forward playback speed.
The negative of this value is for rewind at the same speed. |
public static final int | PLAYBACK_SPEED_FAST_L2The level 2 fast forward playback speed.
The negative of this value is for rewind at the same speed. |
public static final int | PLAYBACK_SPEED_FAST_L3The level 3 fast forward playback speed.
The negative of this value is for rewind at the same speed. |
public static final int | PLAYBACK_SPEED_FAST_L4The level 4 fast forward playback speed.
The negative of this value is for rewind at the same speed. |
private static final String | TAG |
private static final boolean | DEBUG |
private static final int | MSG_UPDATE_PLAYBACK_STATE |
private static final int | UPDATE_PLAYBACK_STATE_DELAY_MS |
private static final int | NUMBER_OF_SEEK_SPEEDS |
private final PlaybackOverlayFragment | mFragment |
private final android.content.Context | mContext |
private final int[] | mFastForwardSpeeds |
private final int[] | mRewindSpeeds |
private android.support.v17.leanback.widget.PlaybackControlsRow | mControlsRow |
private android.support.v17.leanback.widget.SparseArrayObjectAdapter | mPrimaryActionsAdapter |
private PlaybackControlsRow.PlayPauseAction | mPlayPauseAction |
private PlaybackControlsRow.SkipNextAction | mSkipNextAction |
private PlaybackControlsRow.SkipPreviousAction | mSkipPreviousAction |
private PlaybackControlsRow.FastForwardAction | mFastForwardAction |
private PlaybackControlsRow.RewindAction | mRewindAction |
private android.support.v17.leanback.widget.OnItemViewClickedListener | mExternalOnItemViewClickedListener |
private int | mPlaybackSpeed |
private boolean | mFadeWhenPlaying |
private final android.os.Handler | mHandler |
private final android.support.v17.leanback.widget.OnItemViewClickedListener | mOnItemViewClickedListener |
private final PlaybackOverlayFragment.InputEventHandler | mInputEventHandler |
Methods Summary |
---|
public android.support.v17.leanback.widget.PlaybackControlsRowPresenter | createControlsRowAndPresenter()Helper method for instantiating a
{@link android.support.v17.leanback.widget.PlaybackControlsRow} and corresponding
{@link android.support.v17.leanback.widget.PlaybackControlsRowPresenter}.
PlaybackControlsRow controlsRow = new PlaybackControlsRow(this);
setControlsRow(controlsRow);
return new PlaybackControlsRowPresenter(new AbstractDetailsDescriptionPresenter() {
@Override
protected void onBindDescription(AbstractDetailsDescriptionPresenter.ViewHolder
viewHolder, Object object) {
PlaybackControlGlue glue = (PlaybackControlGlue) object;
if (glue.hasValidMedia()) {
viewHolder.getTitle().setText(glue.getMediaTitle());
viewHolder.getSubtitle().setText(glue.getMediaSubtitle());
} else {
viewHolder.getTitle().setText("");
viewHolder.getSubtitle().setText("");
}
}
});
|
protected android.support.v17.leanback.widget.SparseArrayObjectAdapter | createPrimaryActionsAdapter(android.support.v17.leanback.widget.PresenterSelector presenterSelector)Creates the primary action adapter. May be overridden to add additional primary
actions to the adapter.
return new SparseArrayObjectAdapter(presenterSelector);
|
public void | enableProgressUpdating(boolean enable)Override this to start/stop a runnable to call {@link #updateProgress} at
an interval such as {@link #getUpdatePeriod}.
|
public android.content.Context | getContext()Returns the context.
return mContext;
|
public android.support.v17.leanback.widget.PlaybackControlsRow | getControlsRow()Returns the playback controls row managed by the glue layer.
return mControlsRow;
|
public abstract int | getCurrentPosition()Returns the current position of the media item in milliseconds.
|
public abstract int | getCurrentSpeedId()Returns the current playback speed. When playing normally,
{@link #PLAYBACK_SPEED_NORMAL} should be returned.
|
public int[] | getFastForwardSpeeds()Returns the fast forward speeds.
return mFastForwardSpeeds;
|
public PlaybackOverlayFragment | getFragment()Returns the fragment.
return mFragment;
|
private int | getMaxForwardSpeedId()
return PLAYBACK_SPEED_FAST_L0 + (mFastForwardSpeeds.length - 1);
|
private int | getMaxRewindSpeedId()
return PLAYBACK_SPEED_FAST_L0 + (mRewindSpeeds.length - 1);
|
public abstract android.graphics.drawable.Drawable | getMediaArt()Returns a bitmap of the art for the media item.
|
public abstract int | getMediaDuration()Returns the duration of the media item in milliseconds.
|
public abstract java.lang.CharSequence | getMediaSubtitle()Returns the subtitle of the media item.
|
public abstract java.lang.CharSequence | getMediaTitle()Returns the title of the media item.
|
public android.support.v17.leanback.widget.OnItemViewClickedListener | getOnItemViewClickedListener()Returns the {@link OnItemViewClickedListener}.
return mExternalOnItemViewClickedListener;
|
public int[] | getRewindSpeeds()Returns the rewind speeds.
return mRewindSpeeds;
|
private static java.lang.String | getSpeedString(int speed)
switch (speed) {
case PLAYBACK_SPEED_INVALID:
return "PLAYBACK_SPEED_INVALID";
case PLAYBACK_SPEED_PAUSED:
return "PLAYBACK_SPEED_PAUSED";
case PLAYBACK_SPEED_NORMAL:
return "PLAYBACK_SPEED_NORMAL";
case PLAYBACK_SPEED_FAST_L0:
return "PLAYBACK_SPEED_FAST_L0";
case PLAYBACK_SPEED_FAST_L1:
return "PLAYBACK_SPEED_FAST_L1";
case PLAYBACK_SPEED_FAST_L2:
return "PLAYBACK_SPEED_FAST_L2";
case PLAYBACK_SPEED_FAST_L3:
return "PLAYBACK_SPEED_FAST_L3";
case PLAYBACK_SPEED_FAST_L4:
return "PLAYBACK_SPEED_FAST_L4";
case -PLAYBACK_SPEED_FAST_L0:
return "-PLAYBACK_SPEED_FAST_L0";
case -PLAYBACK_SPEED_FAST_L1:
return "-PLAYBACK_SPEED_FAST_L1";
case -PLAYBACK_SPEED_FAST_L2:
return "-PLAYBACK_SPEED_FAST_L2";
case -PLAYBACK_SPEED_FAST_L3:
return "-PLAYBACK_SPEED_FAST_L3";
case -PLAYBACK_SPEED_FAST_L4:
return "-PLAYBACK_SPEED_FAST_L4";
}
return null;
|
public abstract long | getSupportedActions()Returns a bitmask of actions supported by the media player.
|
public int | getUpdatePeriod()Returns the time period in milliseconds that should be used
to update the progress. See {@link #updateProgress()}.
// TODO: calculate a better update period based on total duration and screen size
return 500;
|
private boolean | handleActionClicked(android.support.v17.leanback.widget.Action action)
boolean handled = false;
if (action == mPlayPauseAction) {
if (mPlaybackSpeed != PLAYBACK_SPEED_NORMAL) {
mPlaybackSpeed = PLAYBACK_SPEED_NORMAL;
startPlayback(mPlaybackSpeed);
} else {
mPlaybackSpeed = PLAYBACK_SPEED_PAUSED;
pausePlayback();
}
updatePlaybackStatusAfterUserAction();
handled = true;
} else if (action == mSkipNextAction) {
skipToNext();
handled = true;
} else if (action == mSkipPreviousAction) {
skipToPrevious();
handled = true;
} else if (action == mFastForwardAction) {
if (mPlaybackSpeed < getMaxForwardSpeedId()) {
switch (mPlaybackSpeed) {
case PLAYBACK_SPEED_NORMAL:
case PLAYBACK_SPEED_PAUSED:
mPlaybackSpeed = PLAYBACK_SPEED_FAST_L0;
break;
case PLAYBACK_SPEED_FAST_L0:
case PLAYBACK_SPEED_FAST_L1:
case PLAYBACK_SPEED_FAST_L2:
case PLAYBACK_SPEED_FAST_L3:
mPlaybackSpeed++;
break;
}
startPlayback(mPlaybackSpeed);
updatePlaybackStatusAfterUserAction();
}
handled = true;
} else if (action == mRewindAction) {
if (mPlaybackSpeed > -getMaxRewindSpeedId()) {
switch (mPlaybackSpeed) {
case PLAYBACK_SPEED_NORMAL:
case PLAYBACK_SPEED_PAUSED:
mPlaybackSpeed = -PLAYBACK_SPEED_FAST_L0;
break;
case -PLAYBACK_SPEED_FAST_L0:
case -PLAYBACK_SPEED_FAST_L1:
case -PLAYBACK_SPEED_FAST_L2:
case -PLAYBACK_SPEED_FAST_L3:
mPlaybackSpeed--;
break;
}
startPlayback(mPlaybackSpeed);
updatePlaybackStatusAfterUserAction();
}
handled = true;
}
return handled;
|
public abstract boolean | hasValidMedia()Returns true if there is a valid media item.
|
public boolean | isFadingEnabled()Returns true if controls are set to fade when media is playing.
return mFadeWhenPlaying;
|
public abstract boolean | isMediaPlaying()Returns true if media is currently playing.
|
private static void | notifyItemChanged(android.support.v17.leanback.widget.SparseArrayObjectAdapter adapter, java.lang.Object object)
int index = adapter.indexOf(object);
if (index >= 0) {
adapter.notifyArrayItemRangeChanged(index, 1);
}
|
protected void | onMetadataChanged()Must be called appropriately by a subclass when the metadata state has changed.
if (DEBUG) Log.v(TAG, "onMetadataChanged");
updateRowMetadata();
|
protected abstract void | onRowChanged(android.support.v17.leanback.widget.PlaybackControlsRow row)Invoked when the playback controls row has changed. The adapter containing this row
should be notified.
|
protected void | onStateChanged()Must be called appropriately by a subclass when the playback state has changed.
if (DEBUG) Log.v(TAG, "onStateChanged");
// If a pending control button update is present, delay
// the update until the state settles.
if (!hasValidMedia()) {
return;
}
if (mHandler.hasMessages(MSG_UPDATE_PLAYBACK_STATE)) {
mHandler.removeMessages(MSG_UPDATE_PLAYBACK_STATE);
if (getCurrentSpeedId() != mPlaybackSpeed) {
if (DEBUG) Log.v(TAG, "Status expectation mismatch, delaying update");
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_PLAYBACK_STATE,
UPDATE_PLAYBACK_STATE_DELAY_MS);
} else {
if (DEBUG) Log.v(TAG, "Update state matches expectation");
updatePlaybackState();
}
} else {
updatePlaybackState();
}
|
protected abstract void | pausePlayback()Pause playback.
|
public void | setControlsRow(android.support.v17.leanback.widget.PlaybackControlsRow controlsRow)Sets the controls row to be managed by the glue layer.
The primary actions and playback state related aspects of the row
are updated by the glue.
mControlsRow = controlsRow;
mPrimaryActionsAdapter = createPrimaryActionsAdapter(
new ControlButtonPresenterSelector());
mControlsRow.setPrimaryActionsAdapter(mPrimaryActionsAdapter);
updateControlsRow();
|
public void | setFadingEnabled(boolean enable)Sets the controls to fade after a timeout when media is playing.
mFadeWhenPlaying = enable;
if (!mFadeWhenPlaying) {
mFragment.setFadingEnabled(false);
}
|
public void | setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener listener)Set the {@link OnItemViewClickedListener} to be called if the click event
is not handled internally.
mExternalOnItemViewClickedListener = listener;
|
protected abstract void | skipToNext()Skip to the next track.
|
protected abstract void | skipToPrevious()Skip to the previous track.
|
protected abstract void | startPlayback(int speed)Start playback at the given speed.
|
private void | updateControlsRow()
updateRowMetadata();
mHandler.removeMessages(MSG_UPDATE_PLAYBACK_STATE);
updatePlaybackState();
|
private void | updatePlaybackState()
if (hasValidMedia()) {
mPlaybackSpeed = getCurrentSpeedId();
updatePlaybackState(mPlaybackSpeed);
}
|
private void | updatePlaybackState(int playbackSpeed)
if (mControlsRow == null) {
return;
}
final long actions = getSupportedActions();
if ((actions & ACTION_SKIP_TO_PREVIOUS) != 0) {
if (mSkipPreviousAction == null) {
mSkipPreviousAction = new PlaybackControlsRow.SkipPreviousAction(mContext);
}
mPrimaryActionsAdapter.set(ACTION_SKIP_TO_PREVIOUS, mSkipPreviousAction);
} else {
mPrimaryActionsAdapter.clear(ACTION_SKIP_TO_PREVIOUS);
mSkipPreviousAction = null;
}
if ((actions & ACTION_REWIND) != 0) {
if (mRewindAction == null) {
mRewindAction = new PlaybackControlsRow.RewindAction(mContext,
mRewindSpeeds.length);
}
mPrimaryActionsAdapter.set(ACTION_REWIND, mRewindAction);
} else {
mPrimaryActionsAdapter.clear(ACTION_REWIND);
mRewindAction = null;
}
if ((actions & ACTION_PLAY_PAUSE) != 0) {
if (mPlayPauseAction == null) {
mPlayPauseAction = new PlaybackControlsRow.PlayPauseAction(mContext);
}
mPrimaryActionsAdapter.set(ACTION_PLAY_PAUSE, mPlayPauseAction);
} else {
mPrimaryActionsAdapter.clear(ACTION_PLAY_PAUSE);
mPlayPauseAction = null;
}
if ((actions & ACTION_FAST_FORWARD) != 0) {
if (mFastForwardAction == null) {
mFastForwardAction = new PlaybackControlsRow.FastForwardAction(mContext,
mFastForwardSpeeds.length);
}
mPrimaryActionsAdapter.set(ACTION_FAST_FORWARD, mFastForwardAction);
} else {
mPrimaryActionsAdapter.clear(ACTION_FAST_FORWARD);
mFastForwardAction = null;
}
if ((actions & ACTION_SKIP_TO_NEXT) != 0) {
if (mSkipNextAction == null) {
mSkipNextAction = new PlaybackControlsRow.SkipNextAction(mContext);
}
mPrimaryActionsAdapter.set(ACTION_SKIP_TO_NEXT, mSkipNextAction);
} else {
mPrimaryActionsAdapter.clear(ACTION_SKIP_TO_NEXT);
mSkipNextAction = null;
}
if (mFastForwardAction != null) {
int index = 0;
if (playbackSpeed >= PLAYBACK_SPEED_FAST_L0) {
index = playbackSpeed - PLAYBACK_SPEED_FAST_L0;
if (playbackSpeed < getMaxForwardSpeedId()) {
index++;
}
}
if (mFastForwardAction.getIndex() != index) {
mFastForwardAction.setIndex(index);
notifyItemChanged(mPrimaryActionsAdapter, mFastForwardAction);
}
}
if (mRewindAction != null) {
int index = 0;
if (playbackSpeed <= -PLAYBACK_SPEED_FAST_L0) {
index = -playbackSpeed - PLAYBACK_SPEED_FAST_L0;
if (-playbackSpeed < getMaxRewindSpeedId()) {
index++;
}
}
if (mRewindAction.getIndex() != index) {
mRewindAction.setIndex(index);
notifyItemChanged(mPrimaryActionsAdapter, mRewindAction);
}
}
if (playbackSpeed == PLAYBACK_SPEED_PAUSED) {
updateProgress();
enableProgressUpdating(false);
} else {
enableProgressUpdating(true);
}
if (mFadeWhenPlaying) {
mFragment.setFadingEnabled(playbackSpeed == PLAYBACK_SPEED_NORMAL);
}
if (mPlayPauseAction != null) {
int index = playbackSpeed == PLAYBACK_SPEED_PAUSED ?
PlaybackControlsRow.PlayPauseAction.PLAY :
PlaybackControlsRow.PlayPauseAction.PAUSE;
if (mPlayPauseAction.getIndex() != index) {
mPlayPauseAction.setIndex(index);
notifyItemChanged(mPrimaryActionsAdapter, mPlayPauseAction);
}
}
|
private void | updatePlaybackStatusAfterUserAction()
updatePlaybackState(mPlaybackSpeed);
// Sync playback state after a delay
mHandler.removeMessages(MSG_UPDATE_PLAYBACK_STATE);
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_PLAYBACK_STATE,
UPDATE_PLAYBACK_STATE_DELAY_MS);
|
public void | updateProgress()Updates the progress bar based on the current media playback position.
int position = getCurrentPosition();
if (DEBUG) Log.v(TAG, "updateProgress " + position);
mControlsRow.setCurrentTime(position);
|
private void | updateRowMetadata()
if (mControlsRow == null) {
return;
}
if (DEBUG) Log.v(TAG, "updateRowMetadata hasValidMedia " + hasValidMedia());
if (!hasValidMedia()) {
mControlsRow.setImageDrawable(null);
mControlsRow.setTotalTime(0);
mControlsRow.setCurrentTime(0);
} else {
mControlsRow.setImageDrawable(getMediaArt());
mControlsRow.setTotalTime(getMediaDuration());
mControlsRow.setCurrentTime(getCurrentPosition());
}
onRowChanged(mControlsRow);
|