Implement SlidingPlaybackActivity
This commit is contained in:
parent
ffb2c1332a
commit
9e42e86296
@ -66,6 +66,39 @@ THE SOFTWARE.
|
||||
android:orientation="horizontal">
|
||||
<include layout="@layout/bottombar_controls" android:id="@+id/bottombar_controls" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_gravity="top"
|
||||
android:background="?overlay_background_color"
|
||||
android:elevation="2dp"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/elapsed"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:paddingLeft="5dip" />
|
||||
<SeekBar
|
||||
android:id="@+id/seek_bar"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0px"
|
||||
android:layout_gravity="center"
|
||||
android:paddingTop="5dip"
|
||||
android:paddingBottom="5dip"
|
||||
android:paddingLeft="18dip"
|
||||
android:paddingRight="18dip"
|
||||
android:layout_weight="1" />
|
||||
<TextView
|
||||
android:id="@+id/duration"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:paddingRight="5dip" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -32,7 +32,6 @@ import android.media.MediaMetadataRetriever;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.content.ContentResolver;
|
||||
import android.view.Gravity;
|
||||
@ -54,9 +53,8 @@ import android.content.DialogInterface;
|
||||
/**
|
||||
* The primary playback screen with playback controls and large cover display.
|
||||
*/
|
||||
public class FullPlaybackActivity extends PlaybackActivity
|
||||
implements SeekBar.OnSeekBarChangeListener
|
||||
, View.OnLongClickListener
|
||||
public class FullPlaybackActivity extends SlidingPlaybackActivity
|
||||
implements View.OnLongClickListener
|
||||
{
|
||||
public static final int DISPLAY_INFO_OVERLAP = 0;
|
||||
public static final int DISPLAY_INFO_BELOW = 1;
|
||||
@ -65,10 +63,7 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
private TextView mOverlayText;
|
||||
private View mControlsTop;
|
||||
|
||||
private SeekBar mSeekBar;
|
||||
private TableLayout mInfoTable;
|
||||
private TextView mElapsedView;
|
||||
private TextView mDurationView;
|
||||
private TextView mQueuePosView;
|
||||
|
||||
private TextView mTitle;
|
||||
@ -83,12 +78,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
* True if the extra info is visible.
|
||||
*/
|
||||
private boolean mExtraInfoVisible;
|
||||
/**
|
||||
* Current song duration in milliseconds.
|
||||
*/
|
||||
private long mDuration;
|
||||
private boolean mSeekBarTracking;
|
||||
private boolean mPaused;
|
||||
|
||||
/**
|
||||
* The current display mode, which determines layout and cover render style.
|
||||
@ -98,10 +87,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
private Action mCoverPressAction;
|
||||
private Action mCoverLongPressAction;
|
||||
|
||||
/**
|
||||
* Cached StringBuilder for formatting track position.
|
||||
*/
|
||||
private final StringBuilder mTimeBuilder = new StringBuilder();
|
||||
/**
|
||||
* The currently playing song.
|
||||
*/
|
||||
@ -172,11 +157,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
mArtist = (TextView)findViewById(R.id.artist);
|
||||
|
||||
mControlsTop = findViewById(R.id.controls_top);
|
||||
mElapsedView = (TextView)findViewById(R.id.elapsed);
|
||||
mDurationView = (TextView)findViewById(R.id.duration);
|
||||
mSeekBar = (SeekBar)findViewById(R.id.seek_bar);
|
||||
mSeekBar.setMax(1000);
|
||||
mSeekBar.setOnSeekBarChangeListener(this);
|
||||
mQueuePosView = (TextView)findViewById(R.id.queue_pos);
|
||||
|
||||
mGenreView = (TextView)findViewById(R.id.genre);
|
||||
@ -190,7 +170,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
|
||||
setControlsVisible(settings.getBoolean(PrefKeys.VISIBLE_CONTROLS, PrefDefaults.VISIBLE_CONTROLS));
|
||||
setExtraInfoVisible(settings.getBoolean(PrefKeys.VISIBLE_EXTRA_INFO, PrefDefaults.VISIBLE_EXTRA_INFO));
|
||||
setDuration(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -208,21 +187,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
mCoverLongPressAction = Action.getAction(settings, PrefKeys.COVER_LONGPRESS_ACTION, PrefDefaults.COVER_LONGPRESS_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
mPaused = false;
|
||||
updateElapsedTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
mPaused = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the message overlay, if it exists.
|
||||
*/
|
||||
@ -276,18 +240,12 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
}
|
||||
}
|
||||
|
||||
if ((state & PlaybackService.FLAG_PLAYING) != 0)
|
||||
updateElapsedTime();
|
||||
|
||||
if (mQueuePosView != null)
|
||||
updateQueuePosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSongChange(Song song)
|
||||
{
|
||||
setDuration(song == null ? 0 : song.duration);
|
||||
|
||||
protected void onSongChange(Song song) {
|
||||
if (mTitle != null) {
|
||||
if (song == null) {
|
||||
mTitle.setText(null);
|
||||
@ -302,7 +260,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
}
|
||||
|
||||
mCurrentSong = song;
|
||||
updateElapsedTime();
|
||||
|
||||
mHandler.sendEmptyMessage(MSG_LOAD_FAVOURITE_INFO);
|
||||
|
||||
@ -338,25 +295,14 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
mUiHandler.sendEmptyMessage(MSG_UPDATE_POSITION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current song duration fields.
|
||||
*
|
||||
* @param duration The new duration, in milliseconds.
|
||||
*/
|
||||
private void setDuration(long duration)
|
||||
{
|
||||
mDuration = duration;
|
||||
mDurationView.setText(DateUtils.formatElapsedTime(mTimeBuilder, duration / 1000));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
super.onCreateOptionsMenu(menu);
|
||||
menu.add(0, MENU_DELETE, 0, R.string.delete);
|
||||
menu.add(0, MENU_ENQUEUE_ALBUM, 0, R.string.enqueue_current_album).setIcon(R.drawable.ic_menu_add);
|
||||
menu.add(0, MENU_ENQUEUE_ARTIST, 0, R.string.enqueue_current_artist).setIcon(R.drawable.ic_menu_add);
|
||||
menu.add(0, MENU_ENQUEUE_GENRE, 0, R.string.enqueue_current_genre).setIcon(R.drawable.ic_menu_add);
|
||||
menu.add(0, MENU_DELETE, 30, R.string.delete);
|
||||
menu.add(0, MENU_ENQUEUE_ALBUM, 30, R.string.enqueue_current_album).setIcon(R.drawable.ic_menu_add);
|
||||
menu.add(0, MENU_ENQUEUE_ARTIST, 30, R.string.enqueue_current_artist).setIcon(R.drawable.ic_menu_add);
|
||||
menu.add(0, MENU_ENQUEUE_GENRE, 30, R.string.enqueue_current_genre).setIcon(R.drawable.ic_menu_add);
|
||||
mFavorites = menu.add(0, MENU_SONG_FAVORITE, 0, R.string.add_to_favorites).setIcon(R.drawable.btn_rating_star_off_mtrl_alpha).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
|
||||
// ensure that mFavorites is updated
|
||||
@ -471,28 +417,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update seek bar progress and schedule another update in one second
|
||||
*/
|
||||
private void updateElapsedTime()
|
||||
{
|
||||
long position = PlaybackService.hasInstance() ? PlaybackService.get(this).getPosition() : 0;
|
||||
|
||||
if (!mSeekBarTracking) {
|
||||
long duration = mDuration;
|
||||
mSeekBar.setProgress(duration == 0 ? 0 : (int)(1000 * position / duration));
|
||||
}
|
||||
|
||||
mElapsedView.setText(DateUtils.formatElapsedTime(mTimeBuilder, position / 1000));
|
||||
|
||||
if (!mPaused && mControlsVisible && (mState & PlaybackService.FLAG_PLAYING) != 0) {
|
||||
// Try to update right after the duration increases by one second
|
||||
long next = 1050 - position % 1000;
|
||||
mUiHandler.removeMessages(MSG_UPDATE_PROGRESS);
|
||||
mUiHandler.sendEmptyMessageDelayed(MSG_UPDATE_PROGRESS, next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the visibility of the controls views.
|
||||
*
|
||||
@ -507,7 +431,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
|
||||
if (visible) {
|
||||
mPlayPauseButton.requestFocus();
|
||||
updateElapsedTime();
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,39 +541,30 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
return mime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the seekbar progress with the current song progress. This must be
|
||||
* called on the UI Handler.
|
||||
*/
|
||||
private static final int MSG_UPDATE_PROGRESS = 10;
|
||||
/**
|
||||
* Save the hidden_controls preference to storage.
|
||||
*/
|
||||
private static final int MSG_SAVE_CONTROLS = 14;
|
||||
private static final int MSG_SAVE_CONTROLS = 10;
|
||||
/**
|
||||
* Call {@link #loadExtraInfo()}.
|
||||
*/
|
||||
private static final int MSG_LOAD_EXTRA_INFO = 15;
|
||||
private static final int MSG_LOAD_EXTRA_INFO = 11;
|
||||
/**
|
||||
* Pass obj to mExtraInfo.setText()
|
||||
*/
|
||||
private static final int MSG_COMMIT_INFO = 16;
|
||||
private static final int MSG_COMMIT_INFO = 12;
|
||||
/**
|
||||
* Calls {@link #updateQueuePosition()}.
|
||||
*/
|
||||
private static final int MSG_UPDATE_POSITION = 17;
|
||||
/**
|
||||
* Calls {@link PlaybackService#seekToProgress(int)}.
|
||||
*/
|
||||
private static final int MSG_SEEK_TO_PROGRESS = 18;
|
||||
private static final int MSG_UPDATE_POSITION = 13;
|
||||
/**
|
||||
* Check if passed song is a favorite
|
||||
*/
|
||||
private static final int MSG_LOAD_FAVOURITE_INFO = 19;
|
||||
private static final int MSG_LOAD_FAVOURITE_INFO = 14;
|
||||
/**
|
||||
* Updates the favorites state
|
||||
*/
|
||||
private static final int MSG_COMMIT_FAVOURITE_INFO = 20;
|
||||
private static final int MSG_COMMIT_FAVOURITE_INFO = 15;
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message message)
|
||||
@ -663,9 +577,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
case MSG_UPDATE_PROGRESS:
|
||||
updateElapsedTime();
|
||||
break;
|
||||
case MSG_LOAD_EXTRA_INFO:
|
||||
loadExtraInfo();
|
||||
break;
|
||||
@ -681,10 +592,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
case MSG_UPDATE_POSITION:
|
||||
updateQueuePosition();
|
||||
break;
|
||||
case MSG_SEEK_TO_PROGRESS:
|
||||
PlaybackService.get(this).seekToProgress(message.arg1);
|
||||
updateElapsedTime();
|
||||
break;
|
||||
case MSG_LOAD_FAVOURITE_INFO:
|
||||
if (mCurrentSong != null) {
|
||||
boolean found = Playlist.isInPlaylist(getContentResolver(), Playlist.getFavoritesId(this, false), mCurrentSong);
|
||||
@ -705,28 +612,6 @@ public class FullPlaybackActivity extends PlaybackActivity
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
|
||||
{
|
||||
if (fromUser) {
|
||||
mElapsedView.setText(DateUtils.formatElapsedTime(mTimeBuilder, progress * mDuration / 1000000));
|
||||
mUiHandler.removeMessages(MSG_SEEK_TO_PROGRESS);
|
||||
mUiHandler.sendMessageDelayed(mUiHandler.obtainMessage(MSG_SEEK_TO_PROGRESS, progress, 0), 150);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
mSeekBarTracking = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
mSeekBarTracking = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performAction(Action action)
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ import junit.framework.Assert;
|
||||
* The library activity where songs to play can be selected from the library.
|
||||
*/
|
||||
public class LibraryActivity
|
||||
extends PlaybackActivity
|
||||
extends SlidingPlaybackActivity
|
||||
implements DialogInterface.OnClickListener
|
||||
, DialogInterface.OnDismissListener
|
||||
, SearchView.OnQueryTextListener
|
||||
@ -800,12 +800,10 @@ public class LibraryActivity
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
// called before super to have it on top
|
||||
menu.add(0, MENU_PLAYBACK, 0, R.string.playback_view);
|
||||
super.onCreateOptionsMenu(menu);
|
||||
|
||||
menu.add(0, MENU_PLAYBACK, 0, R.string.playback_view);
|
||||
menu.add(0, MENU_SEARCH, 0, R.string.search).setIcon(R.drawable.ic_menu_search).setVisible(false);
|
||||
menu.add(0, MENU_SORT, 0, R.string.sort_by).setIcon(R.drawable.ic_menu_sort_alphabetically);
|
||||
menu.add(0, MENU_SORT, 30, R.string.sort_by).setIcon(R.drawable.ic_menu_sort_alphabetically);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -57,12 +57,10 @@ public abstract class PlaybackActivity extends Activity
|
||||
implements TimelineCallback,
|
||||
Handler.Callback,
|
||||
View.OnClickListener,
|
||||
CoverView.Callback,
|
||||
SlidingView.Callback
|
||||
CoverView.Callback
|
||||
{
|
||||
private Action mUpAction;
|
||||
private Action mDownAction;
|
||||
private Menu mMenu;
|
||||
|
||||
/**
|
||||
* A Handler running on the UI thread, in contrast with mHandler which runs
|
||||
@ -82,7 +80,6 @@ public abstract class PlaybackActivity extends Activity
|
||||
protected ImageButton mPlayPauseButton;
|
||||
protected ImageButton mShuffleButton;
|
||||
protected ImageButton mEndButton;
|
||||
protected SlidingView mSlidingView;
|
||||
|
||||
protected int mState;
|
||||
private long mLastStateEvent;
|
||||
@ -318,10 +315,6 @@ public abstract class PlaybackActivity extends Activity
|
||||
mEndButton = (ImageButton)findViewById(R.id.end_action);
|
||||
mEndButton.setOnClickListener(this);
|
||||
registerForContextMenu(mEndButton);
|
||||
|
||||
mSlidingView = (SlidingView)findViewById(R.id.sliding_view);
|
||||
if (mSlidingView != null)
|
||||
mSlidingView.setCallback(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -385,15 +378,7 @@ public abstract class PlaybackActivity extends Activity
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
mMenu = menu;
|
||||
menu.add(0, MENU_PREFS, 0, R.string.settings).setIcon(R.drawable.ic_menu_preferences);
|
||||
menu.add(0, MENU_SHOW_QUEUE, 0, R.string.show_queue);
|
||||
menu.add(0, MENU_HIDE_QUEUE, 0, R.string.hide_queue);
|
||||
menu.add(0, MENU_CLEAR_QUEUE, 0, R.string.dequeue_rest);
|
||||
menu.add(0, MENU_EMPTY_QUEUE, 0, R.string.empty_the_queue);
|
||||
menu.add(0, MENU_SAVE_QUEUE_AS_PLAYLIST, 0, R.string.save_as_playlist);
|
||||
|
||||
onSlideFullyExpanded(false);
|
||||
menu.add(0, MENU_PREFS, 10, R.string.settings).setIcon(R.drawable.ic_menu_preferences);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -407,12 +392,6 @@ public abstract class PlaybackActivity extends Activity
|
||||
case MENU_CLEAR_QUEUE:
|
||||
PlaybackService.get(this).clearQueue();
|
||||
break;
|
||||
case MENU_SHOW_QUEUE:
|
||||
mSlidingView.expandSlide();
|
||||
break;
|
||||
case MENU_HIDE_QUEUE:
|
||||
mSlidingView.hideSlide();
|
||||
break;
|
||||
case MENU_EMPTY_QUEUE:
|
||||
PlaybackService.get(this).emptyQueue();
|
||||
break;
|
||||
@ -428,33 +407,6 @@ public abstract class PlaybackActivity extends Activity
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by SlidingView to signal a visibility change.
|
||||
* Toggles the visibility of menu items
|
||||
*
|
||||
* @param expanded true if slide fully expanded
|
||||
*/
|
||||
@Override
|
||||
public void onSlideFullyExpanded(boolean expanded) {
|
||||
if (mMenu == null)
|
||||
return; // not initialized yet
|
||||
|
||||
final int[] slide_visible = {MENU_HIDE_QUEUE, MENU_CLEAR_QUEUE, MENU_EMPTY_QUEUE, MENU_SAVE_QUEUE_AS_PLAYLIST};
|
||||
final int[] slide_hidden = {MENU_SHOW_QUEUE, MENU_SORT, MENU_DELETE, MENU_ENQUEUE_ALBUM, MENU_ENQUEUE_ARTIST, MENU_ENQUEUE_GENRE};
|
||||
|
||||
for (int id : slide_visible) {
|
||||
MenuItem item = mMenu.findItem(id);
|
||||
if (item != null)
|
||||
item.setVisible(expanded);
|
||||
}
|
||||
|
||||
for (int id : slide_hidden) {
|
||||
MenuItem item = mMenu.findItem(id);
|
||||
if (item != null)
|
||||
item.setVisible(!expanded);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call addToPlaylist with the results from a NewPlaylistDialog stored in
|
||||
* obj.
|
||||
|
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Adrian Ulrich <adrian@blinkenlights.ch>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package ch.blinkenlights.android.vanilla;
|
||||
|
||||
import android.text.format.DateUtils;
|
||||
import android.os.Message;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class SlidingPlaybackActivity extends PlaybackActivity
|
||||
implements SlidingView.Callback,
|
||||
SeekBar.OnSeekBarChangeListener
|
||||
{
|
||||
/**
|
||||
* Reference to the inflated menu
|
||||
*/
|
||||
private Menu mMenu;
|
||||
/**
|
||||
* SeekBar widget
|
||||
*/
|
||||
private SeekBar mSeekBar;
|
||||
/**
|
||||
* TextView indicating the elapsed playback time
|
||||
*/
|
||||
private TextView mElapsedView;
|
||||
/**
|
||||
* TextView indicating the total duration of the song
|
||||
*/
|
||||
private TextView mDurationView;
|
||||
/**
|
||||
* Current song duration in milliseconds.
|
||||
*/
|
||||
private long mDuration;
|
||||
/**
|
||||
* True if user tracks/drags the seek bar
|
||||
*/
|
||||
private boolean mSeekBarTracking;
|
||||
/**
|
||||
* True if the seek bar should not get periodic updates
|
||||
*/
|
||||
private boolean mPaused;
|
||||
/**
|
||||
* Cached StringBuilder for formatting track position.
|
||||
*/
|
||||
private final StringBuilder mTimeBuilder = new StringBuilder();
|
||||
/**
|
||||
* Instance of the sliding view
|
||||
*/
|
||||
protected SlidingView mSlidingView;
|
||||
|
||||
@Override
|
||||
protected void bindControlButtons() {
|
||||
super.bindControlButtons();
|
||||
|
||||
mSlidingView = (SlidingView)findViewById(R.id.sliding_view);
|
||||
mSlidingView.setCallback(this);
|
||||
mElapsedView = (TextView)findViewById(R.id.elapsed);
|
||||
mDurationView = (TextView)findViewById(R.id.duration);
|
||||
mSeekBar = (SeekBar)findViewById(R.id.seek_bar);
|
||||
mSeekBar.setMax(1000);
|
||||
mSeekBar.setOnSeekBarChangeListener(this);
|
||||
setDuration(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mPaused = false;
|
||||
updateElapsedTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mPaused = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSongChange(Song song) {
|
||||
setDuration(song == null ? 0 : song.duration);
|
||||
updateElapsedTime();
|
||||
super.onSongChange(song);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStateChange(int state, int toggled) {
|
||||
updateElapsedTime();
|
||||
super.onStateChange(state, toggled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
|
||||
mMenu = menu;
|
||||
menu.add(0, MENU_SHOW_QUEUE, 20, R.string.show_queue);
|
||||
menu.add(0, MENU_HIDE_QUEUE, 20, R.string.hide_queue);
|
||||
menu.add(0, MENU_CLEAR_QUEUE, 20, R.string.dequeue_rest);
|
||||
menu.add(0, MENU_EMPTY_QUEUE, 20, R.string.empty_the_queue);
|
||||
menu.add(0, MENU_SAVE_QUEUE_AS_PLAYLIST, 20, R.string.save_as_playlist);
|
||||
onSlideFullyExpanded(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_SHOW_QUEUE:
|
||||
mSlidingView.expandSlide();
|
||||
break;
|
||||
case MENU_HIDE_QUEUE:
|
||||
mSlidingView.hideSlide();
|
||||
break;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the seekbar progress with the current song progress. This must be
|
||||
* called on the UI Handler.
|
||||
*/
|
||||
private static final int MSG_UPDATE_PROGRESS = 20;
|
||||
/**
|
||||
* Calls {@link PlaybackService#seekToProgress(int)}.
|
||||
*/
|
||||
private static final int MSG_SEEK_TO_PROGRESS = 21;
|
||||
@Override
|
||||
public boolean handleMessage(Message message)
|
||||
{
|
||||
switch (message.what) {
|
||||
case MSG_UPDATE_PROGRESS:
|
||||
updateElapsedTime();
|
||||
break;
|
||||
case MSG_SEEK_TO_PROGRESS:
|
||||
PlaybackService.get(this).seekToProgress(message.arg1);
|
||||
updateElapsedTime();
|
||||
break;
|
||||
default:
|
||||
return super.handleMessage(message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current song duration fields.
|
||||
*
|
||||
* @param duration The new duration, in milliseconds.
|
||||
*/
|
||||
private void setDuration(long duration) {
|
||||
mDuration = duration;
|
||||
mDurationView.setText(DateUtils.formatElapsedTime(mTimeBuilder, duration / 1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update seek bar progress and schedule another update in one second
|
||||
*/
|
||||
private void updateElapsedTime() {
|
||||
long position = PlaybackService.hasInstance() ? PlaybackService.get(this).getPosition() : 0;
|
||||
|
||||
if (!mSeekBarTracking) {
|
||||
long duration = mDuration;
|
||||
mSeekBar.setProgress(duration == 0 ? 0 : (int)(1000 * position / duration));
|
||||
}
|
||||
|
||||
mElapsedView.setText(DateUtils.formatElapsedTime(mTimeBuilder, position / 1000));
|
||||
|
||||
if (!mPaused && (mState & PlaybackService.FLAG_PLAYING) != 0) {
|
||||
// Try to update right after the duration increases by one second
|
||||
long next = 1050 - position % 1000;
|
||||
mUiHandler.removeMessages(MSG_UPDATE_PROGRESS);
|
||||
mUiHandler.sendEmptyMessageDelayed(MSG_UPDATE_PROGRESS, next);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
mElapsedView.setText(DateUtils.formatElapsedTime(mTimeBuilder, progress * mDuration / 1000000));
|
||||
mUiHandler.removeMessages(MSG_SEEK_TO_PROGRESS);
|
||||
mUiHandler.sendMessageDelayed(mUiHandler.obtainMessage(MSG_SEEK_TO_PROGRESS, progress, 0), 150);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
mSeekBarTracking = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
mSeekBarTracking = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by SlidingView to signal a visibility change.
|
||||
* Toggles the visibility of menu items
|
||||
*
|
||||
* @param expanded true if slide fully expanded
|
||||
*/
|
||||
@Override
|
||||
public void onSlideFullyExpanded(boolean expanded) {
|
||||
if (mMenu == null)
|
||||
return; // not initialized yet
|
||||
|
||||
final int[] slide_visible = {MENU_HIDE_QUEUE, MENU_CLEAR_QUEUE, MENU_EMPTY_QUEUE, MENU_SAVE_QUEUE_AS_PLAYLIST};
|
||||
final int[] slide_hidden = {MENU_SHOW_QUEUE, MENU_SORT, MENU_DELETE, MENU_ENQUEUE_ALBUM, MENU_ENQUEUE_ARTIST, MENU_ENQUEUE_GENRE};
|
||||
|
||||
for (int id : slide_visible) {
|
||||
MenuItem item = mMenu.findItem(id);
|
||||
if (item != null)
|
||||
item.setVisible(expanded);
|
||||
}
|
||||
|
||||
for (int id : slide_hidden) {
|
||||
MenuItem item = mMenu.findItem(id);
|
||||
if (item != null)
|
||||
item.setVisible(!expanded);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user