2 * Copyright (C) 2012 Andrew Neal Licensed under the Apache License, Version 2.0
3 * (the "License"); you may not use this file except in compliance with the
4 * License. You may obtain a copy of the License at
5 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
6 * or agreed to in writing, software distributed under the License is
7 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8 * KIND, either express or implied. See the License for the specific language
9 * governing permissions and limitations under the License.
12 package com.cyngn.eleven.ui.fragments.profile;
14 import android.os.Bundle;
15 import android.support.v4.app.Fragment;
16 import android.support.v4.app.LoaderManager.LoaderCallbacks;
17 import android.support.v4.content.Loader;
18 import android.view.ContextMenu;
19 import android.view.ContextMenu.ContextMenuInfo;
20 import android.view.LayoutInflater;
21 import android.view.Menu;
22 import android.view.SubMenu;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.widget.AbsListView;
26 import android.widget.AdapterView;
27 import android.widget.AdapterView.AdapterContextMenuInfo;
28 import android.widget.AdapterView.OnItemClickListener;
29 import android.widget.ListView;
30 import android.widget.TextView;
32 import com.cyngn.eleven.R;
33 import com.cyngn.eleven.adapters.SongAdapter;
34 import com.cyngn.eleven.menu.CreateNewPlaylist;
35 import com.cyngn.eleven.menu.DeleteDialog;
36 import com.cyngn.eleven.menu.FragmentMenuItems;
37 import com.cyngn.eleven.model.Song;
38 import com.cyngn.eleven.recycler.RecycleHolder;
39 import com.cyngn.eleven.utils.MusicUtils;
40 import com.cyngn.eleven.utils.NavUtils;
41 import com.cyngn.eleven.widgets.NoResultsContainer;
43 import java.util.List;
46 * This class is used to display all of the songs
48 * @author Andrew Neal (andrewdneal@gmail.com)
50 public abstract class BasicSongFragment extends Fragment implements LoaderCallbacks<List<Song>>,
56 protected ViewGroup mRootView;
59 * The adapter for the list
61 protected SongAdapter mAdapter;
66 protected ListView mListView;
74 * Position of a context menu item
76 protected int mSelectedPosition;
79 * Id of a context menu item
81 protected long mSelectedId;
84 * Song, album, and artist name used in the context menu
86 protected String mSongName, mAlbumName, mArtistName;
89 * Empty constructor as per the {@link Fragment} documentation
91 public BasicSongFragment() {
98 public void onCreate(final Bundle savedInstanceState) {
99 super.onCreate(savedInstanceState);
100 // Create the adpater
101 mAdapter = createAdapter();
108 public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
109 final Bundle savedInstanceState) {
110 // The View for the fragment's UI
111 mRootView = (ViewGroup) inflater.inflate(R.layout.list_base, null);
112 // Initialize the list
113 mListView = (ListView) mRootView.findViewById(R.id.list_base);
114 // Set the data behind the list
115 mListView.setAdapter(mAdapter);
116 // Release any references to the recycled Views
117 mListView.setRecyclerListener(new RecycleHolder());
118 // Listen for ContextMenus to be created
119 mListView.setOnCreateContextMenuListener(this);
120 // Play the selected song
121 mListView.setOnItemClickListener(this);
122 // To help make scrolling smooth
123 mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
125 public void onScrollStateChanged(AbsListView view, int scrollState) {
126 // Pause disk cache access to ensure smoother scrolling
127 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING
128 || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
129 mAdapter.setPauseDiskCache(true);
131 mAdapter.setPauseDiskCache(false);
132 mAdapter.notifyDataSetChanged();
137 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
146 * This allows subclasses to customize the look and feel of the no results container
147 * @param empty NoResultsContainer class
149 public void setupNoResultsContainer(final NoResultsContainer empty) {
157 public void onActivityCreated(final Bundle savedInstanceState) {
158 super.onActivityCreated(savedInstanceState);
159 // Enable the options menu
160 setHasOptionsMenu(true);
162 getLoaderManager().initLoader(getLoaderId(), null, this);
169 public void onCreateContextMenu(final ContextMenu menu, final View v,
170 final ContextMenuInfo menuInfo) {
171 super.onCreateContextMenu(menu, v, menuInfo);
172 // Get the position of the selected item
173 final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
174 mSelectedPosition = info.position;
176 mSong = mAdapter.getItem(mSelectedPosition);
177 mSelectedId = mSong.mSongId;
178 mSongName = mSong.mSongName;
179 mAlbumName = mSong.mAlbumName;
180 mArtistName = mSong.mArtistName;
183 menu.add(getGroupId(), FragmentMenuItems.PLAY_SELECTION, Menu.NONE,
184 getString(R.string.context_menu_play_selection));
187 menu.add(getGroupId(), FragmentMenuItems.PLAY_NEXT, Menu.NONE,
188 getString(R.string.context_menu_play_next));
190 // Add the song to the queue
191 menu.add(getGroupId(), FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE,
192 getString(R.string.add_to_queue));
194 // Add the song to a playlist
195 final SubMenu subMenu = menu.addSubMenu(getGroupId(), FragmentMenuItems.ADD_TO_PLAYLIST,
196 Menu.NONE, R.string.add_to_playlist);
197 MusicUtils.makePlaylistMenu(getActivity(), getGroupId(), subMenu);
199 // View more content by the song artist
200 menu.add(getGroupId(), FragmentMenuItems.MORE_BY_ARTIST, Menu.NONE,
201 getString(R.string.context_menu_more_by_artist));
203 // Make the song a ringtone
204 menu.add(getGroupId(), FragmentMenuItems.USE_AS_RINGTONE, Menu.NONE,
205 getString(R.string.context_menu_use_as_ringtone));
208 menu.add(getGroupId(), FragmentMenuItems.DELETE, Menu.NONE,
209 getString(R.string.context_menu_delete));
213 public boolean onContextItemSelected(final android.view.MenuItem item) {
214 if (item.getGroupId() == getGroupId()) {
215 switch (item.getItemId()) {
216 case FragmentMenuItems.PLAY_SELECTION:
217 MusicUtils.playAll(getActivity(), new long[]{
221 case FragmentMenuItems.PLAY_NEXT:
222 MusicUtils.playNext(new long[]{
226 case FragmentMenuItems.ADD_TO_QUEUE:
227 MusicUtils.addToQueue(getActivity(), new long[]{
231 case FragmentMenuItems.NEW_PLAYLIST:
232 CreateNewPlaylist.getInstance(new long[]{
234 }).show(getFragmentManager(), "CreatePlaylist");
236 case FragmentMenuItems.PLAYLIST_SELECTED:
237 final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0);
238 MusicUtils.addToPlaylist(getActivity(), new long[]{
242 case FragmentMenuItems.MORE_BY_ARTIST:
243 NavUtils.openArtistProfile(getActivity(), mArtistName);
245 case FragmentMenuItems.USE_AS_RINGTONE:
246 MusicUtils.setRingtone(getActivity(), mSelectedId);
248 case FragmentMenuItems.DELETE:
249 // TODO: Smarter refresh
250 DeleteDialog.newInstance(mSong.mSongName, new long[]{
252 }, null).show(getFragmentManager(), "DeleteDialog");
258 return super.onContextItemSelected(item);
265 public void onItemClick(final AdapterView<?> parent, final View view, final int position,
274 public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) {
275 // Check for any errors
276 if (data.isEmpty()) {
277 // Set the empty text
278 final NoResultsContainer empty = (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
279 mListView.setEmptyView(empty);
285 // Add the data to the adpater
286 for (final Song song : data) {
291 mAdapter.buildCache();
294 public void restartLoader() {
295 getLoaderManager().restartLoader(getLoaderId(), null, this);
302 public void onLoaderReset(final Loader<List<Song>> loader) {
303 // Clear the data in the adapter
308 * If the subclasses want to use a customized SongADapter
309 * @return the Song adapter
311 protected SongAdapter createAdapter() {
312 return new SongAdapter(
314 R.layout.list_item_normal
320 * Used to keep context menu items from bleeding into other fragments
322 public abstract int getGroupId();
325 * LoaderCallbacks identifier
327 public abstract int getLoaderId();
330 * If the user clisk play all
332 * @param position the position of the item clicked or -1 if shuffle all
334 public abstract void playAll(int position);