package com.cyngn.eleven.ui.fragments.profile;
+import android.app.Activity;
import android.os.Bundle;
+import android.os.SystemClock;
import android.support.v4.app.Fragment;
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.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
-import android.widget.TextView;
+import com.cyngn.eleven.MusicStateListener;
import com.cyngn.eleven.R;
import com.cyngn.eleven.adapters.SongAdapter;
-import com.cyngn.eleven.menu.CreateNewPlaylist;
-import com.cyngn.eleven.menu.DeleteDialog;
-import com.cyngn.eleven.menu.FragmentMenuItems;
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.sectionadapter.SectionAdapter;
+import com.cyngn.eleven.sectionadapter.SectionListContainer;
+import com.cyngn.eleven.ui.activities.BaseActivity;
+import com.cyngn.eleven.utils.PopupMenuHelper;
+import com.cyngn.eleven.utils.SongPopupMenuHelper;
+import com.cyngn.eleven.widgets.IPopupMenuCallback;
import com.cyngn.eleven.widgets.NoResultsContainer;
-import java.util.List;
+import java.util.TreeSet;
/**
* This class is used to display all of the songs
*
* @author Andrew Neal (andrewdneal@gmail.com)
*/
-public abstract class BasicSongFragment extends Fragment implements LoaderCallbacks<List<Song>>,
- OnItemClickListener {
+public abstract class BasicSongFragment extends Fragment implements
+ LoaderCallbacks<SectionListContainer<Song>>, OnItemClickListener, MusicStateListener {
/**
* Fragment UI
/**
* The adapter for the list
*/
- protected SongAdapter mAdapter;
+ protected SectionAdapter<Song, SongAdapter> mAdapter;
/**
* The list view
protected ListView mListView;
/**
- * Represents a song
+ * Pop up menu helper
*/
- protected Song mSong;
+ private PopupMenuHelper mPopupMenuHelper;
/**
- * Position of a context menu item
- */
- protected int mSelectedPosition;
-
- /**
- * Id of a context menu item
- */
- protected long mSelectedId;
-
- /**
- * Song, album, and artist name used in the context menu
+ * Empty constructor as per the {@link Fragment} documentation
*/
- protected String mSongName, mAlbumName, mArtistName;
+ public BasicSongFragment() {
+ }
/**
- * Empty constructor as per the {@link Fragment} documentation
+ * {@inheritDoc}
*/
- public BasicSongFragment() {
+ @Override
+ public void onAttach(final Activity activity) {
+ super.onAttach(activity);
+ // Register the music status listener
+ ((BaseActivity)activity).setMusicStateListenerListener(this);
}
/**
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // Create the adpater
+ mPopupMenuHelper = new SongPopupMenuHelper(getActivity(), getFragmentManager()) {
+ @Override
+ public Song getSong(int position) {
+ return mAdapter.getTItem(position);
+ }
+
+ @Override
+ protected void updateMenuIds(PopupMenuType type, TreeSet<Integer> set) {
+ super.updateMenuIds(type, set);
+ BasicSongFragment.this.updateMenuIds(set);
+ }
+ };
+
+ // Create the adapter
mAdapter = createAdapter();
+ mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
+ @Override
+ public void onPopupMenuClicked(View v, int position) {
+ mPopupMenuHelper.showPopupMenu(v, position);
+ }
+ });
+ }
+
+ protected void updateMenuIds(TreeSet<Integer> set) {
+ // do nothing - let subclasses override
}
/**
mListView.setAdapter(mAdapter);
// Release any references to the recycled Views
mListView.setRecyclerListener(new RecycleHolder());
- // Listen for ContextMenus to be created
- mListView.setOnCreateContextMenuListener(this);
// Play the selected song
mListView.setOnItemClickListener(this);
// To help make scrolling smooth
// 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);
+ mAdapter.getUnderlyingAdapter().setPauseDiskCache(true);
} else {
- mAdapter.setPauseDiskCache(false);
+ mAdapter.getUnderlyingAdapter().setPauseDiskCache(false);
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- // Enable the options menu
- setHasOptionsMenu(true);
// Start the loader
getLoaderManager().initLoader(getLoaderId(), null, this);
}
* {@inheritDoc}
*/
@Override
- public void onCreateContextMenu(final ContextMenu menu, final View v,
- final ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
- // Get the position of the selected item
- final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- mSelectedPosition = info.position;
- // Creat a new song
- mSong = mAdapter.getItem(mSelectedPosition);
- mSelectedId = mSong.mSongId;
- mSongName = mSong.mSongName;
- mAlbumName = mSong.mAlbumName;
- mArtistName = mSong.mArtistName;
-
- // Play the song
- menu.add(getGroupId(), FragmentMenuItems.PLAY_SELECTION, Menu.NONE,
- getString(R.string.context_menu_play_selection));
-
- // Play next
- menu.add(getGroupId(), FragmentMenuItems.PLAY_NEXT, Menu.NONE,
- getString(R.string.context_menu_play_next));
-
- // Add the song to the queue
- menu.add(getGroupId(), FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE,
- getString(R.string.add_to_queue));
-
- // Add the song to a playlist
- final SubMenu subMenu = menu.addSubMenu(getGroupId(), FragmentMenuItems.ADD_TO_PLAYLIST,
- Menu.NONE, R.string.add_to_playlist);
- MusicUtils.makePlaylistMenu(getActivity(), getGroupId(), subMenu);
-
- // View more content by the song artist
- menu.add(getGroupId(), FragmentMenuItems.MORE_BY_ARTIST, Menu.NONE,
- getString(R.string.context_menu_more_by_artist));
-
- // Make the song a ringtone
- menu.add(getGroupId(), FragmentMenuItems.USE_AS_RINGTONE, Menu.NONE,
- getString(R.string.context_menu_use_as_ringtone));
-
- // Delete the song
- menu.add(getGroupId(), FragmentMenuItems.DELETE, Menu.NONE,
- getString(R.string.context_menu_delete));
- }
-
- @Override
- public boolean onContextItemSelected(final android.view.MenuItem item) {
- if (item.getGroupId() == getGroupId()) {
- switch (item.getItemId()) {
- case FragmentMenuItems.PLAY_SELECTION:
- MusicUtils.playAll(getActivity(), new long[]{
- mSelectedId
- }, 0, false);
- return true;
- case FragmentMenuItems.PLAY_NEXT:
- MusicUtils.playNext(new long[]{
- mSelectedId
- });
- return true;
- case FragmentMenuItems.ADD_TO_QUEUE:
- MusicUtils.addToQueue(getActivity(), new long[]{
- mSelectedId
- });
- return true;
- case FragmentMenuItems.NEW_PLAYLIST:
- CreateNewPlaylist.getInstance(new long[]{
- mSelectedId
- }).show(getFragmentManager(), "CreatePlaylist");
- return true;
- case FragmentMenuItems.PLAYLIST_SELECTED:
- final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0);
- MusicUtils.addToPlaylist(getActivity(), new long[]{
- mSelectedId
- }, mPlaylistId);
- return true;
- case FragmentMenuItems.MORE_BY_ARTIST:
- NavUtils.openArtistProfile(getActivity(), mArtistName);
- return true;
- case FragmentMenuItems.USE_AS_RINGTONE:
- MusicUtils.setRingtone(getActivity(), mSelectedId);
- return true;
- case FragmentMenuItems.DELETE:
- // TODO: Smarter refresh
- DeleteDialog.newInstance(mSong.mSongName, new long[]{
- mSelectedId
- }, null).show(getFragmentManager(), "DeleteDialog");
- return true;
- default:
- break;
- }
- }
- return super.onContextItemSelected(item);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public void onItemClick(final AdapterView<?> parent, final View view, final int position,
final long id) {
playAll(position);
* {@inheritDoc}
*/
@Override
- public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) {
+ public void onLoadFinished(final Loader<SectionListContainer<Song>> loader,
+ final SectionListContainer<Song> data) {
// Check for any errors
- if (data.isEmpty()) {
+ if (data.mListResults.isEmpty()) {
// Set the empty text
- final NoResultsContainer empty = (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
+ final NoResultsContainer empty =
+ (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
+ // Setup the container strings
+ setupNoResultsContainer(empty);
+ // set the empty view into the list view
mListView.setEmptyView(empty);
return;
}
// Start fresh
- mAdapter.unload();
- // Add the data to the adpater
- for (final Song song : data) {
- mAdapter.add(song);
- }
+ mAdapter.setData(data);
+ }
- // Build the cache
- mAdapter.buildCache();
+ /**
+ * Restarts the loader.
+ */
+ public void refresh() {
+ // Wait a moment for the preference to change.
+ SystemClock.sleep(10);
+ getLoaderManager().restartLoader(getLoaderId(), null, this);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void restartLoader() {
+ // Update the list when the user deletes any items
getLoaderManager().restartLoader(getLoaderId(), null, this);
}
* {@inheritDoc}
*/
@Override
- public void onLoaderReset(final Loader<List<Song>> loader) {
+ public void onLoaderReset(final Loader<SectionListContainer<Song>> loader) {
// Clear the data in the adapter
mAdapter.unload();
}
/**
- * If the subclasses want to use a customized SongADapter
+ * If the subclasses want to use a customized SongAdapter they can override this method
* @return the Song adapter
*/
- protected SongAdapter createAdapter() {
- return new SongAdapter(
- getActivity(),
- R.layout.list_item_normal
+ protected SectionAdapter<Song, SongAdapter> createAdapter() {
+ return new SectionAdapter(getActivity(),
+ new SongAdapter(
+ getActivity(),
+ R.layout.list_item_normal
+ )
);
}
-
- /**
- * Used to keep context menu items from bleeding into other fragments
- */
- public abstract int getGroupId();
+ @Override
+ public void onMetaChanged() {
+ // do nothing
+ }
/**
* LoaderCallbacks identifier