summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml7
-rw-r--r--res/drawable-xxhdpi/playlist_icon.pngbin0 -> 387 bytes
-rw-r--r--res/drawable-xxhdpi/stopwatch_icon_white.pngbin0 -> 893 bytes
-rw-r--r--res/layout/faux_playlist_header.xml25
-rw-r--r--res/layout/playlist_detail.xml19
-rw-r--r--res/layout/playlist_detail_header.xml60
-rw-r--r--res/values/colors.xml2
-rw-r--r--res/values/dimens.xml3
-rw-r--r--res/values/strings.xml4
-rw-r--r--src/com/cyngn/eleven/adapters/ProfileSongAdapter.java17
-rw-r--r--src/com/cyngn/eleven/adapters/SongAdapter.java2
-rw-r--r--src/com/cyngn/eleven/ui/activities/PlaylistDetailActivity.java (renamed from src/com/cyngn/eleven/ui/fragments/profile/PlaylistSongFragment.java)391
-rw-r--r--src/com/cyngn/eleven/ui/activities/ProfileActivity.java26
-rw-r--r--src/com/cyngn/eleven/ui/fragments/AudioPlayerFragment.java4
-rw-r--r--src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java1
-rw-r--r--src/com/cyngn/eleven/ui/fragments/profile/LastAddedFragment.java1
-rw-r--r--src/com/cyngn/eleven/utils/MusicUtils.java35
-rw-r--r--src/com/cyngn/eleven/utils/NavUtils.java3
18 files changed, 370 insertions, 230 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4ef165c..db70871 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -146,6 +146,13 @@
android:screenOrientation="portrait"
android:theme="@style/Eleven.Theme.ActionBar.Overlay">
</activity>
+ <!-- Playlist Detail Activity -->
+ <activity
+ android:name=".ui.activities.PlaylistDetailActivity"
+ android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
+ android:theme="@style/Eleven.Theme.ActionBar.Overlay">
+ </activity>
<!-- Shortcut launcher Activity -->
<activity
android:name=".ui.activities.ShortcutActivity"
diff --git a/res/drawable-xxhdpi/playlist_icon.png b/res/drawable-xxhdpi/playlist_icon.png
new file mode 100644
index 0000000..1be226b
--- /dev/null
+++ b/res/drawable-xxhdpi/playlist_icon.png
Binary files differ
diff --git a/res/drawable-xxhdpi/stopwatch_icon_white.png b/res/drawable-xxhdpi/stopwatch_icon_white.png
new file mode 100644
index 0000000..2f4059a
--- /dev/null
+++ b/res/drawable-xxhdpi/stopwatch_icon_white.png
Binary files differ
diff --git a/res/layout/faux_playlist_header.xml b/res/layout/faux_playlist_header.xml
new file mode 100644
index 0000000..59ab140
--- /dev/null
+++ b/res/layout/faux_playlist_header.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 Andrew Neal
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <include
+ layout="@layout/playlist_detail_header"
+ android:visibility="invisible" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/res/layout/playlist_detail.xml b/res/layout/playlist_detail.xml
new file mode 100644
index 0000000..458737e
--- /dev/null
+++ b/res/layout/playlist_detail.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Cyanogen, Inc.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ layout="@layout/list_base_nopadding" />
+
+ <include
+ android:id="@+id/playlist_header"
+ layout="@layout/playlist_detail_header" />
+</RelativeLayout> \ No newline at end of file
diff --git a/res/layout/playlist_detail_header.xml b/res/layout/playlist_detail_header.xml
new file mode 100644
index 0000000..93c2429
--- /dev/null
+++ b/res/layout/playlist_detail_header.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2014 Cyanogen, Inc.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/playlist_detail_header_height">
+
+ <com.cyngn.eleven.widgets.LayoutSuppressingImageView
+ android:id="@+id/image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:contentDescription="@null"
+ android:scaleType="centerCrop" />
+
+ <FrameLayout
+ android:layout_width="fill_parent"
+ android:layout_height="@dimen/playlist_detail_header_bottom_height"
+ android:layout_alignParentBottom="true"
+ android:background="@color/header_shadow_color">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:scaleType="centerInside"
+ android:src="@drawable/playlist_icon" />
+
+ <TextView
+ android:id="@+id/number_of_songs_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-light"
+ android:paddingRight="16dp"
+ android:textColor="@color/white"
+ android:textSize="@dimen/text_size_micro" />
+
+ <ImageView
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:scaleType="centerInside"
+ android:src="@drawable/stopwatch_icon_white" />
+
+ <TextView
+ android:id="@+id/duration_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-light"
+ android:textColor="@color/white"
+ android:textSize="@dimen/text_size_micro" />
+ </LinearLayout>
+ </FrameLayout>
+</RelativeLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 62579cb..1cc9430 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -66,6 +66,8 @@
<color name="header_action_bar_text_color">@color/white</color>
<color name="bottom_action_bar_text_color">@color/default_text_color_light</color>
+ <!-- Color for background for shadow on playlist page -->
+ <color name="header_shadow_color">#ea31353f</color>
<!-- Color for the pop up menu -->
<color name="menu_divider_color">#4ca19d9e</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 6437a23..7fd95f0 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -94,6 +94,9 @@
<dimen name="profile_carousel_label_height">45.0dip</dimen>
<dimen name="profile_indicator_height">5.0dip</dimen>
<dimen name="profile_label_padding">16.0dip</dimen>
+ <!-- playlist detail header -->
+ <dimen name="playlist_detail_header_height">240.0dip</dimen>
+ <dimen name="playlist_detail_header_bottom_height">40.0dip</dimen>
<!-- Audio player Buttons (play/pause/shuffle/repeat/next/previous)-->
<dimen name="audio_player_controls_end_button_width">30.0dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ec7e719..84ac14c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -202,4 +202,8 @@
<string name="header_5_plus_albums">5+ Albums</string>
<string name="combine_two_strings">%1$s | %2$s</string>
+
+ <string name="duration_mins"><xliff:g id="format">%3$dm %4$ds</xliff:g></string>
+ <string name="duration_hours"><xliff:g id="format">%2$dh %3$dm %4$ds</xliff:g></string>
+ <string name="duration_days"><xliff:g id="format">%1$dd %2$dd %3$dm %4$ds</xliff:g></string>
</resources>
diff --git a/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java b/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java
index 7d80133..52f4bf1 100644
--- a/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java
+++ b/src/com/cyngn/eleven/adapters/ProfileSongAdapter.java
@@ -12,7 +12,6 @@
package com.cyngn.eleven.adapters;
import android.app.Activity;
-import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -27,7 +26,7 @@ import com.cyngn.eleven.ui.fragments.profile.AlbumSongFragment;
import com.cyngn.eleven.ui.fragments.profile.ArtistSongFragment;
import com.cyngn.eleven.ui.fragments.profile.GenreSongFragment;
import com.cyngn.eleven.ui.fragments.profile.LastAddedFragment;
-import com.cyngn.eleven.ui.fragments.profile.PlaylistSongFragment;
+import com.cyngn.eleven.ui.activities.PlaylistDetailActivity;
import com.cyngn.eleven.utils.ApolloUtils;
import com.cyngn.eleven.utils.Lists;
import com.cyngn.eleven.utils.MusicUtils;
@@ -37,7 +36,7 @@ import java.util.List;
/**
* This {@link ArrayAdapter} is used to display the songs for a particular
* artist, album, playlist, or genre for {@link ArtistSongFragment},
- * {@link AlbumSongFragment},{@link PlaylistSongFragment},
+ * {@link AlbumSongFragment},{@link PlaylistDetailActivity},
* {@link GenreSongFragment},{@link LastAddedFragment}.
*
* @author Andrew Neal (andrewdneal@gmail.com)
@@ -116,12 +115,12 @@ public class ProfileSongAdapter extends ArrayAdapter<Song> {
* @param layoutId The resource Id of the view to inflate.
* @param setting defines the content of the second line
*/
- public ProfileSongAdapter(final Activity activity, final int layoutId, final int setting) {
+ public ProfileSongAdapter(final Activity activity, final int layoutId, final int headerId, final int setting) {
super(activity, 0);
// Used to create the custom layout
mInflater = LayoutInflater.from(activity);
// Cache the header
- mHeader = mInflater.inflate(R.layout.faux_carousel, null);
+ mHeader = mInflater.inflate(headerId, null);
// Get the layout Id
mLayoutId = layoutId;
// Know what to put in line two
@@ -137,7 +136,7 @@ public class ProfileSongAdapter extends ArrayAdapter<Song> {
* @param layoutId The resource Id of the view to inflate.
*/
public ProfileSongAdapter(final Activity activity, final int layoutId) {
- this(activity, layoutId, DISPLAY_DEFAULT_SETTING);
+ this(activity, layoutId, R.layout.faux_carousel, DISPLAY_DEFAULT_SETTING);
}
/**
@@ -177,7 +176,7 @@ public class ProfileSongAdapter extends ArrayAdapter<Song> {
holder.mLineOneRight.get().setVisibility(View.GONE);
holder.mLineTwo.get().setText(
- MusicUtils.makeTimeString(getContext(), song.mDuration));
+ MusicUtils.makeShortTimeString(getContext(), song.mDuration));
break;
case DISPLAY_PLAYLIST_SETTING:
if (song.mDuration == -1) {
@@ -185,7 +184,7 @@ public class ProfileSongAdapter extends ArrayAdapter<Song> {
} else {
holder.mLineOneRight.get().setVisibility(View.VISIBLE);
holder.mLineOneRight.get().setText(
- MusicUtils.makeTimeString(getContext(), song.mDuration));
+ MusicUtils.makeShortTimeString(getContext(), song.mDuration));
}
final StringBuilder sb = new StringBuilder(song.mArtistName);
@@ -204,7 +203,7 @@ public class ProfileSongAdapter extends ArrayAdapter<Song> {
holder.mLineOneRight.get().setVisibility(View.VISIBLE);
holder.mLineOneRight.get().setText(
- MusicUtils.makeTimeString(getContext(), song.mDuration));
+ MusicUtils.makeShortTimeString(getContext(), song.mDuration));
holder.mLineTwo.get().setText(song.mAlbumName);
break;
}
diff --git a/src/com/cyngn/eleven/adapters/SongAdapter.java b/src/com/cyngn/eleven/adapters/SongAdapter.java
index ac38cf0..6e3c8d2 100644
--- a/src/com/cyngn/eleven/adapters/SongAdapter.java
+++ b/src/com/cyngn/eleven/adapters/SongAdapter.java
@@ -162,7 +162,7 @@ public class SongAdapter extends ArrayAdapter<Song> implements SectionAdapter.Ba
// Song names (line one)
mData[i].mLineOne = song.mSongName;
// Song duration (line one, right)
- mData[i].mLineOneRight = MusicUtils.makeTimeString(getContext(), song.mDuration);
+ mData[i].mLineOneRight = MusicUtils.makeShortTimeString(getContext(), song.mDuration);
// Album names (line two)
mData[i].mLineTwo = song.mAlbumName;
}
diff --git a/src/com/cyngn/eleven/ui/fragments/profile/PlaylistSongFragment.java b/src/com/cyngn/eleven/ui/activities/PlaylistDetailActivity.java
index e67be06..e6134b7 100644
--- a/src/com/cyngn/eleven/ui/fragments/profile/PlaylistSongFragment.java
+++ b/src/com/cyngn/eleven/ui/activities/PlaylistDetailActivity.java
@@ -1,40 +1,33 @@
-/*
- * Copyright (C) 2012 Andrew Neal Licensed under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
- * or agreed to in writing, software distributed under the License is
- * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
- */
-
-package com.cyngn.eleven.ui.fragments.profile;
-
-import android.app.Activity;
+package com.cyngn.eleven.ui.activities;
+
+import android.app.ActionBar;
import android.database.Cursor;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.provider.MediaStore;
-import android.support.v4.app.Fragment;
+import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.cyngn.eleven.Config;
import com.cyngn.eleven.R;
import com.cyngn.eleven.adapters.ProfileSongAdapter;
+import com.cyngn.eleven.cache.ImageFetcher;
import com.cyngn.eleven.dragdrop.DragSortListView;
import com.cyngn.eleven.dragdrop.DragSortListView.DragScrollProfile;
import com.cyngn.eleven.dragdrop.DragSortListView.DropListener;
@@ -47,18 +40,13 @@ import com.cyngn.eleven.model.Song;
import com.cyngn.eleven.recycler.RecycleHolder;
import com.cyngn.eleven.utils.MusicUtils;
import com.cyngn.eleven.utils.NavUtils;
-import com.cyngn.eleven.widgets.ProfileTabCarousel;
-import com.cyngn.eleven.widgets.VerticalScrollListener;
import java.util.List;
+import java.util.Locale;
-/**
- * This class is used to display all of the songs from a particular playlist.
- *
- * @author Andrew Neal (andrewdneal@gmail.com)
- */
-public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<List<Song>>,
- OnItemClickListener, DropListener, RemoveListener, DragScrollProfile {
+public class PlaylistDetailActivity extends SlidingPanelActivity implements
+ OnScrollListener, LoaderCallbacks<List<Song>>, OnItemClickListener, DropListener,
+ RemoveListener, DragScrollProfile {
/**
* Used to keep context menu items from bleeding into other fragments
@@ -70,15 +58,17 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
*/
private static final int LOADER = 0;
- /**
- * The adapter for the list
- */
- private ProfileSongAdapter mAdapter;
+ private static final int ACTION_BAR_DEFAULT_OPACITY = 65;
+ private Drawable mActionBarBackground;
- /**
- * The list view
- */
private DragSortListView mListView;
+ private ProfileSongAdapter mAdapter;
+
+ private View mHeaderContainer;
+ private ImageView mPlaylistImageView;
+
+ private TextView mNumberOfSongs;
+ private TextView mDurationOfPlaylist;
/**
* Represents a song
@@ -101,56 +91,54 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
private String mSongName, mAlbumName, mArtistName;
/**
- * Profile header
- */
- private ProfileTabCarousel mProfileTabCarousel;
-
- /**
* The Id of the playlist the songs belong to
*/
private long mPlaylistId;
- /**
- * Empty constructor as per the {@link Fragment} documentation
- */
- public PlaylistSongFragment() {
- }
-
- /**
- * {@inheritDoc}
- */
@Override
- public void onAttach(final Activity activity) {
- super.onAttach(activity);
- mProfileTabCarousel = (ProfileTabCarousel)activity
- .findViewById(R.id.acivity_profile_base_tab_carousel);
+ protected int getLayoutToInflate() {
+ return R.layout.playlist_detail;
}
- /**
- * {@inheritDoc}
- */
@Override
- public void onCreate(final Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // Create the adpater
+
+ Bundle arguments = getIntent().getExtras();
+ String playlistName = arguments.getString(Config.NAME);
+ mPlaylistId = arguments.getLong(Config.ID);
+
+ setupActionBar(playlistName);
+
+ ViewGroup root = (ViewGroup) findViewById(R.id.activity_base_content);
+ root.setPadding(0, 0, 0, 0); // clear default padding
+
+ setupHero();
+ setupSongList(root);
+
+ LoaderManager lm = getSupportLoaderManager();
+ lm.initLoader(0, arguments, this);
+ }
+
+ private void setupHero() {
+ mPlaylistImageView = (ImageView)findViewById(R.id.image);
+ mHeaderContainer = findViewById(R.id.playlist_header);
+ mNumberOfSongs = (TextView)findViewById(R.id.number_of_songs_text);
+ mDurationOfPlaylist = (TextView)findViewById(R.id.duration_text);
+
+ // TODO: Get the top artist image - do this in the next patch
+ // ImageFetcher.getInstance(this).loadCurrentArtwork(mPlaylistImageView);
+ }
+
+ private void setupSongList(ViewGroup root) {
+ mListView = (DragSortListView) root.findViewById(R.id.list_base);
+ mListView.setOnScrollListener(this);
mAdapter = new ProfileSongAdapter(
- getActivity(),
+ this,
R.layout.edit_track_list_item,
+ R.layout.faux_playlist_header,
ProfileSongAdapter.DISPLAY_PLAYLIST_SETTING
);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
- final Bundle savedInstanceState) {
- // The View for the fragment's UI
- final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.list_base_nopadding, null);
- // Initialize the list
- mListView = (DragSortListView)rootView.findViewById(R.id.list_base);
- // Set the data behind the list
mListView.setAdapter(mAdapter);
// Release any references to the recycled Views
mListView.setRecyclerListener(new RecycleHolder());
@@ -164,52 +152,21 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
mListView.setRemoveListener(this);
// Quick scroll while dragging
mListView.setDragScrollProfile(this);
- // To help make scrolling smooth
- mListView.setOnScrollListener(new VerticalScrollListener(null, mProfileTabCarousel, 0) {
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- super.onScrollStateChanged(view, scrollState);
-
- // Pause disk cache access to ensure smoother scrolling
- if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING
- || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
- mAdapter.setPauseDiskCache(true);
- } else {
- mAdapter.setPauseDiskCache(false);
- mAdapter.notifyDataSetChanged();
- }
- }
- });
// Remove the scrollbars and padding for the fast scroll
mListView.setVerticalScrollBarEnabled(false);
mListView.setFastScrollEnabled(false);
mListView.setPadding(0, 0, 0, 0);
- return rootView;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void onActivityCreated(final Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- // Enable the options menu
- setHasOptionsMenu(true);
- // Start the loader
- final Bundle arguments = getArguments();
- if (arguments != null) {
- mPlaylistId = arguments.getLong(Config.ID);
- getLoaderManager().initLoader(LOADER, arguments, this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onSaveInstanceState(final Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putAll(getArguments() != null ? getArguments() : new Bundle());
+ private void setupActionBar(String playlistName) {
+ ActionBar actionBar = getActionBar();
+ actionBar.setTitle(playlistName.toUpperCase(Locale.getDefault()));
+ actionBar.setIcon(R.drawable.ic_action_back);
+ actionBar.setHomeButtonEnabled(true);
+ // change action bar background to a drawable we can control
+ mActionBarBackground = new ColorDrawable(getResources().getColor(R.color.header_action_bar_color));
+ mActionBarBackground.setAlpha(ACTION_BAR_DEFAULT_OPACITY);
+ actionBar.setBackgroundDrawable(mActionBarBackground);
}
/**
@@ -217,10 +174,10 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
*/
@Override
public void onCreateContextMenu(final ContextMenu menu, final View v,
- final ContextMenuInfo menuInfo) {
+ final ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// Get the position of the selected item
- final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
+ final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
mSelectedPosition = info.position - 1;
// Creat a new song
mSong = mAdapter.getItem(mSelectedPosition);
@@ -244,7 +201,7 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
// Add the song to a playlist
final SubMenu subMenu = menu.addSubMenu(GROUP_ID, FragmentMenuItems.ADD_TO_PLAYLIST,
Menu.NONE, R.string.add_to_playlist);
- MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, subMenu);
+ MusicUtils.makePlaylistMenu(this, GROUP_ID, subMenu);
// View more content by the song artist
menu.add(GROUP_ID, FragmentMenuItems.MORE_BY_ARTIST, Menu.NONE,
@@ -268,50 +225,50 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
if (item.getGroupId() == GROUP_ID) {
switch (item.getItemId()) {
case FragmentMenuItems.PLAY_SELECTION:
- MusicUtils.playAll(getActivity(), new long[] {
- mSelectedId
+ MusicUtils.playAll(this, new long[]{
+ mSelectedId
}, 0, false);
return true;
case FragmentMenuItems.PLAY_NEXT:
- MusicUtils.playNext(new long[] {
- mSelectedId
+ MusicUtils.playNext(new long[]{
+ mSelectedId
});
return true;
case FragmentMenuItems.ADD_TO_QUEUE:
- MusicUtils.addToQueue(getActivity(), new long[] {
- mSelectedId
+ MusicUtils.addToQueue(this, new long[]{
+ mSelectedId
});
return true;
case FragmentMenuItems.NEW_PLAYLIST:
- CreateNewPlaylist.getInstance(new long[] {
- mSelectedId
- }).show(getFragmentManager(), "CreatePlaylist");
+ CreateNewPlaylist.getInstance(new long[]{
+ mSelectedId
+ }).show(getSupportFragmentManager(), "CreatePlaylist");
return true;
case FragmentMenuItems.PLAYLIST_SELECTED:
final long playlistId = item.getIntent().getLongExtra("playlist", 0);
- MusicUtils.addToPlaylist(getActivity(), new long[] {
- mSelectedId
+ MusicUtils.addToPlaylist(this, new long[]{
+ mSelectedId
}, playlistId);
return true;
case FragmentMenuItems.MORE_BY_ARTIST:
- NavUtils.openArtistProfile(getActivity(), mArtistName);
+ NavUtils.openArtistProfile(this, mArtistName);
return true;
case FragmentMenuItems.USE_AS_RINGTONE:
- MusicUtils.setRingtone(getActivity(), mSelectedId);
+ MusicUtils.setRingtone(this, mSelectedId);
return true;
case FragmentMenuItems.DELETE:
- DeleteDialog.newInstance(mSong.mSongName, new long[] {
- mSelectedId
- }, null).show(getFragmentManager(), "DeleteDialog");
+ DeleteDialog.newInstance(mSong.mSongName, new long[]{
+ mSelectedId
+ }, null).show(getSupportFragmentManager(), "DeleteDialog");
SystemClock.sleep(10);
mAdapter.notifyDataSetChanged();
- getLoaderManager().restartLoader(LOADER, null, this);
+ getSupportLoaderManager().restartLoader(LOADER, null, this);
return true;
case FragmentMenuItems.REMOVE_FROM_PLAYLIST:
mAdapter.remove(mSong);
mAdapter.notifyDataSetChanged();
- MusicUtils.removeFromPlaylist(getActivity(), mSong.mSongId, mPlaylistId);
- getLoaderManager().restartLoader(LOADER, null, this);
+ MusicUtils.removeFromPlaylist(this, mSong.mSongId, mPlaylistId);
+ getSupportLoaderManager().restartLoader(LOADER, null, this);
return true;
default:
break;
@@ -324,60 +281,6 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
* {@inheritDoc}
*/
@Override
- public void onItemClick(final AdapterView<?> parent, final View view, final int position,
- final long id) {
- if (position == 0) {
- return;
- }
- Cursor cursor = PlaylistSongLoader.makePlaylistSongCursor(getActivity(),
- getArguments().getLong(Config.ID));
- final long[] list = MusicUtils.getSongListForCursor(cursor);
- MusicUtils.playAll(getActivity(), list, position - 1, false);
- cursor.close();
- cursor = null;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Loader<List<Song>> onCreateLoader(final int id, final Bundle args) {
- return new PlaylistSongLoader(getActivity(), mPlaylistId);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) {
- // Check for any errors
- if (data.isEmpty()) {
- return;
- }
-
- // Start fresh
- mAdapter.unload();
- // Return the correct count
- mAdapter.setCount(data);
- // Add the data to the adpater
- for (final Song song : data) {
- mAdapter.add(song);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onLoaderReset(final Loader<List<Song>> loader) {
- // Clear the data in the adapter
- mAdapter.unload();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public float getSpeed(final float w, final long t) {
if (w > 0.8f) {
return mAdapter.getCount() / 0.001f;
@@ -395,7 +298,7 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
mAdapter.remove(mSong);
mAdapter.notifyDataSetChanged();
final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", mPlaylistId);
- getActivity().getContentResolver().delete(uri,
+ getContentResolver().delete(uri,
MediaStore.Audio.Playlists.Members.AUDIO_ID + "=" + mSong.mSongId,
null);
}
@@ -415,7 +318,115 @@ public class PlaylistSongFragment extends Fragment implements LoaderCallbacks<Li
mAdapter.remove(mSong);
mAdapter.insert(mSong, realTo);
mAdapter.notifyDataSetChanged();
- MediaStore.Audio.Playlists.Members.moveItem(getActivity().getContentResolver(),
+ MediaStore.Audio.Playlists.Members.moveItem(getContentResolver(),
mPlaylistId, realFrom, realTo);
}
-}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onItemClick(final AdapterView<?> parent, final View view, final int position,
+ final long id) {
+ if (position == 0) {
+ return;
+ }
+ Cursor cursor = PlaylistSongLoader.makePlaylistSongCursor(this,
+ mPlaylistId);
+ final long[] list = MusicUtils.getSongListForCursor(cursor);
+ MusicUtils.playAll(this, list, position - 1, false);
+ cursor.close();
+ cursor = null;
+ }
+
+ /**
+ * cause action bar icon tap to act like back -- boo-urns!
+ */
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ // Pause disk cache access to ensure smoother scrolling
+ if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING
+ || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
+ mAdapter.setPauseDiskCache(true);
+ } else {
+ mAdapter.setPauseDiskCache(false);
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override // OnScrollListener
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ View firstChild = view.getChildAt(0);
+ if (firstChild == null) {
+ return;
+ }
+
+ float firstChildY = firstChild.getY();
+
+ // if the first fake header is off the screen,
+ // set opaque and header container to be off screen
+ if (firstVisibleItem != 0) {
+ mHeaderContainer.setY(-mHeaderContainer.getHeight());
+ mActionBarBackground.setAlpha(255);
+ } else {
+ // otherwise set the offset and calculate the alpha
+ mHeaderContainer.setY(firstChildY);
+ int alpha = ACTION_BAR_DEFAULT_OPACITY +
+ (int)((255 - ACTION_BAR_DEFAULT_OPACITY) * -firstChildY /
+ (float)mHeaderContainer.getHeight());
+
+ alpha = Math.min(255, alpha);
+ mActionBarBackground.setAlpha(alpha);
+ }
+ }
+
+ @Override
+ public Loader<List<Song>> onCreateLoader(int i, Bundle bundle) {
+ return new PlaylistSongLoader(this, mPlaylistId);
+ }
+
+ @Override
+ public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) {
+ // Check for any errors
+ if (data.isEmpty()) {
+ return;
+ }
+
+ // Start fresh
+ mAdapter.unload();
+ // Return the correct count
+ mAdapter.setCount(data);
+ // set the number of songs
+ String numberOfSongs = MusicUtils.makeLabel(this, R.plurals.Nsongs, data.size());
+ mNumberOfSongs.setText(numberOfSongs);
+
+ long duration = 0;
+
+ // Add the data to the adapter
+ for (final Song song : data) {
+ mAdapter.add(song);
+ duration += song.mDuration;
+ }
+
+ // set the duration
+ String durationString = MusicUtils.makeLongTimeString(this, duration);
+ mDurationOfPlaylist.setText(durationString);
+ }
+
+ @Override
+ public void onLoaderReset(final Loader<List<Song>> loader) {
+ // Clear the data in the adapter
+ mAdapter.unload();
+ }
+} \ No newline at end of file
diff --git a/src/com/cyngn/eleven/ui/activities/ProfileActivity.java b/src/com/cyngn/eleven/ui/activities/ProfileActivity.java
index 8d570dd..6b7951d 100644
--- a/src/com/cyngn/eleven/ui/activities/ProfileActivity.java
+++ b/src/com/cyngn/eleven/ui/activities/ProfileActivity.java
@@ -39,7 +39,6 @@ import com.cyngn.eleven.ui.fragments.profile.ArtistAlbumFragment;
import com.cyngn.eleven.ui.fragments.profile.ArtistSongFragment;
import com.cyngn.eleven.ui.fragments.profile.GenreSongFragment;
import com.cyngn.eleven.ui.fragments.profile.LastAddedFragment;
-import com.cyngn.eleven.ui.fragments.profile.PlaylistSongFragment;
import com.cyngn.eleven.utils.ApolloUtils;
import com.cyngn.eleven.utils.MusicUtils;
import com.cyngn.eleven.utils.NavUtils;
@@ -191,17 +190,6 @@ public class ProfileActivity extends SlidingPanelActivity implements OnPageChang
// Action bar title = Last added
getActionBar().setTitle(mProfileName);
} else
- // Set up the user playlist profile
- if (isPlaylist()) {
- // Add the carousel images
- mTabCarousel.setPlaylistOrGenreProfileHeader(this, mProfileName);
-
- // Playlist profile fragments
- mPagerAdapter.add(PlaylistSongFragment.class, mArguments);
-
- // Action bar title = playlist name
- getActionBar().setTitle(mProfileName);
- } else
// Set up the genre profile
if (isGenre()) {
// Add the carousel images
@@ -248,7 +236,7 @@ public class ProfileActivity extends SlidingPanelActivity implements OnPageChang
// Set the shuffle all title to "play all" if a playlist.
final MenuItem shuffle = menu.findItem(R.id.menu_shuffle);
String title = null;
- if (isLastAdded() || isPlaylist()) {
+ if (isLastAdded()) {
title = getString(R.string.menu_play_all);
} else {
title = getString(R.string.menu_shuffle);
@@ -301,9 +289,7 @@ public class ProfileActivity extends SlidingPanelActivity implements OnPageChang
} else if (isGenre()) {
list = MusicUtils.getSongListForGenre(this, id);
}
- if (isPlaylist()) {
- MusicUtils.playPlaylist(this, id);
- } else if (isLastAdded()) {
+ if (isLastAdded()) {
MusicUtils.playLastAdded(this);
} else {
if (list != null && list.length > 0) {
@@ -620,14 +606,6 @@ public class ProfileActivity extends SlidingPanelActivity implements OnPageChang
}
/**
- * @return True if the MIME type is vnd.android.cursor.dir/playlist, false
- * otherwise.
- */
- private final boolean isPlaylist() {
- return mType.equals(MediaStore.Audio.Playlists.CONTENT_TYPE);
- }
-
- /**
* @return True if the MIME type is "LastAdded", false otherwise.
*/
private final boolean isLastAdded() {
diff --git a/src/com/cyngn/eleven/ui/fragments/AudioPlayerFragment.java b/src/com/cyngn/eleven/ui/fragments/AudioPlayerFragment.java
index a47d96b..dbf85d4 100644
--- a/src/com/cyngn/eleven/ui/fragments/AudioPlayerFragment.java
+++ b/src/com/cyngn/eleven/ui/fragments/AudioPlayerFragment.java
@@ -356,7 +356,7 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection {
mTrackName.setText(MusicUtils.getTrackName());
// Set the total time
- String totalTime = MusicUtils.makeTimeString(getActivity(), MusicUtils.duration() / 1000);
+ String totalTime = MusicUtils.makeShortTimeString(getActivity(), MusicUtils.duration() / 1000);
if (!mTotalTime.getText().equals(totalTime)) {
mTotalTime.setText(totalTime);
}
@@ -579,7 +579,7 @@ public class AudioPlayerFragment extends Fragment implements ServiceConnection {
}
private void refreshCurrentTimeText(final long pos) {
- mCurrentTime.setText(MusicUtils.makeTimeString(getActivity(), pos / 1000));
+ mCurrentTime.setText(MusicUtils.makeShortTimeString(getActivity(), pos / 1000));
}
/* Used to update the current time string */
diff --git a/src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java b/src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java
index b99fe8b..46aa066 100644
--- a/src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java
+++ b/src/com/cyngn/eleven/ui/fragments/profile/AlbumSongFragment.java
@@ -124,6 +124,7 @@ public class AlbumSongFragment extends Fragment implements LoaderCallbacks<List<
mAdapter = new ProfileSongAdapter(
getActivity(),
R.layout.list_item_simple,
+ R.layout.faux_carousel,
ProfileSongAdapter.DISPLAY_ALBUM_SETTING
);
}
diff --git a/src/com/cyngn/eleven/ui/fragments/profile/LastAddedFragment.java b/src/com/cyngn/eleven/ui/fragments/profile/LastAddedFragment.java
index ffbf4b6..96a4a18 100644
--- a/src/com/cyngn/eleven/ui/fragments/profile/LastAddedFragment.java
+++ b/src/com/cyngn/eleven/ui/fragments/profile/LastAddedFragment.java
@@ -132,6 +132,7 @@ public class LastAddedFragment extends Fragment implements LoaderCallbacks<List<
mAdapter = new ProfileSongAdapter(
getActivity(),
R.layout.list_item_normal,
+ R.layout.faux_carousel,
ProfileSongAdapter.DISPLAY_PLAYLIST_SETTING
);
}
diff --git a/src/com/cyngn/eleven/utils/MusicUtils.java b/src/com/cyngn/eleven/utils/MusicUtils.java
index d4067ba..edd741e 100644
--- a/src/com/cyngn/eleven/utils/MusicUtils.java
+++ b/src/com/cyngn/eleven/utils/MusicUtils.java
@@ -190,13 +190,13 @@ public final class MusicUtils {
* @param secs The track in seconds.
* @return Duration of a track that's properly formatted.
*/
- public static final String makeTimeString(final Context context, long secs) {
+ public static final String makeShortTimeString(final Context context, long secs) {
long hours, mins;
hours = secs / 3600;
- secs -= hours * 3600;
+ secs %= 3600;
mins = secs / 60;
- secs -= mins * 60;
+ secs %= 60;
final String durationFormat = context.getResources().getString(
hours == 0 ? R.string.durationformatshort : R.string.durationformatlong);
@@ -204,6 +204,34 @@ public final class MusicUtils {
}
/**
+ * * Used to create a formatted time string in the format of #d #h #m #s
+ *
+ * @param context The {@link Context} to use.
+ * @param secs The duration seconds.
+ * @return Duration properly formatted in #d #h #m #s format
+ */
+ public static final String makeLongTimeString(final Context context, long secs) {
+ long days, hours, mins;
+
+ days = secs / (3600 * 24);
+ secs %= (3600 * 24);
+ hours = secs / 3600;
+ secs %= 3600;
+ mins = secs / 60;
+ secs %= 60;
+
+ int stringId = R.string.duration_mins;
+ if (days != 0) {
+ stringId = R.string.duration_days;
+ } else if (hours != 0) {
+ stringId = R.string.duration_hours;
+ }
+
+ final String durationFormat = context.getResources().getString(stringId);
+ return String.format(durationFormat, days, hours, mins, secs);
+ }
+
+ /**
* Changes to the next track
*/
public static void next() {
@@ -1288,6 +1316,7 @@ public final class MusicUtils {
try {
return mService.duration();
} catch (final RemoteException ignored) {
+ } catch (final IllegalStateException ignored) {
}
}
return 0;
diff --git a/src/com/cyngn/eleven/utils/NavUtils.java b/src/com/cyngn/eleven/utils/NavUtils.java
index f18f861..4fdfacb 100644
--- a/src/com/cyngn/eleven/utils/NavUtils.java
+++ b/src/com/cyngn/eleven/utils/NavUtils.java
@@ -23,6 +23,7 @@ import com.cyngn.eleven.Config;
import com.cyngn.eleven.R;
import com.cyngn.eleven.ui.activities.ArtistDetailActivity;
import com.cyngn.eleven.ui.activities.HomeActivity;
+import com.cyngn.eleven.ui.activities.PlaylistDetailActivity;
import com.cyngn.eleven.ui.activities.ProfileActivity;
import com.cyngn.eleven.ui.activities.SearchActivity;
import com.cyngn.eleven.ui.activities.SettingsActivity;
@@ -101,7 +102,7 @@ public final class NavUtils {
bundle.putString(Config.NAME, playlistName);
// Create the intent to launch the profile activity
- final Intent intent = new Intent(context, ProfileActivity.class);
+ final Intent intent = new Intent(context, PlaylistDetailActivity.class);
intent.putExtras(bundle);
context.startActivity(intent);
}