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.andrew.apollo.ui.fragments.profile;
14 import android.app.Activity;
15 import android.os.Bundle;
16 import android.os.SystemClock;
17 import android.support.v4.app.Fragment;
18 import android.support.v4.app.LoaderManager.LoaderCallbacks;
19 import android.support.v4.content.Loader;
20 import android.view.ContextMenu;
21 import android.view.ContextMenu.ContextMenuInfo;
22 import android.view.LayoutInflater;
23 import android.view.Menu;
24 import android.view.MenuItem;
25 import android.view.SubMenu;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.AbsListView;
29 import android.widget.AdapterView;
30 import android.widget.AdapterView.AdapterContextMenuInfo;
31 import android.widget.AdapterView.OnItemClickListener;
32 import android.widget.ListView;
34 import com.andrew.apollo.Config;
35 import com.andrew.apollo.R;
36 import com.andrew.apollo.adapters.ArtistAlbumAdapter;
37 import com.andrew.apollo.loaders.ArtistAlbumLoader;
38 import com.andrew.apollo.menu.CreateNewPlaylist;
39 import com.andrew.apollo.menu.DeleteDialog;
40 import com.andrew.apollo.menu.FragmentMenuItems;
41 import com.andrew.apollo.model.Album;
42 import com.andrew.apollo.recycler.RecycleHolder;
43 import com.andrew.apollo.utils.MusicUtils;
44 import com.andrew.apollo.utils.NavUtils;
45 import com.andrew.apollo.widgets.ProfileTabCarousel;
46 import com.andrew.apollo.widgets.VerticalScrollListener;
47 import com.andrew.apollo.widgets.VerticalScrollListener.ScrollableHeader;
49 import java.util.List;
52 * This class is used to display all of the albums from a particular artist.
54 * @author Andrew Neal (andrewdneal@gmail.com)
56 public class ArtistAlbumFragment extends Fragment implements LoaderCallbacks<List<Album>>,
60 * Used to keep context menu items from bleeding into other fragments
62 private static final int GROUP_ID = 10;
65 * LoaderCallbacks identifier
67 private static final int LOADER = 0;
70 * The adapter for the grid
72 private ArtistAlbumAdapter mAdapter;
77 private ListView mListView;
82 private long[] mAlbumList;
92 private ProfileTabCarousel mProfileTabCarousel;
95 * Empty constructor as per the {@link Fragment} documentation
97 public ArtistAlbumFragment() {
104 public void onAttach(final Activity activity) {
105 super.onAttach(activity);
106 mProfileTabCarousel = (ProfileTabCarousel)activity
107 .findViewById(R.id.acivity_profile_base_tab_carousel);
114 public void onCreate(final Bundle savedInstanceState) {
115 super.onCreate(savedInstanceState);
116 // Create the adpater
117 mAdapter = new ArtistAlbumAdapter(getActivity(),
118 R.layout.list_item_detailed_no_background);
125 public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
126 final Bundle savedInstanceState) {
127 // The View for the fragment's UI
128 final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.list_base, null);
129 // Initialize the list
130 mListView = (ListView)rootView.findViewById(R.id.list_base);
131 // Set the data behind the grid
132 mListView.setAdapter(mAdapter);
133 // Release any references to the recycled Views
134 mListView.setRecyclerListener(new RecycleHolder());
135 // Listen for ContextMenus to be created
136 mListView.setOnCreateContextMenuListener(this);
137 // Show the songs from the selected album
138 mListView.setOnItemClickListener(this);
139 // To help make scrolling smooth
140 mListView.setOnScrollListener(new VerticalScrollListener(mScrollableHeader,
141 mProfileTabCarousel, 1));
142 // Remove the scrollbars and padding for the fast scroll
143 mListView.setVerticalScrollBarEnabled(false);
144 mListView.setFastScrollEnabled(false);
145 mListView.setPadding(0, 0, 0, 0);
153 public void onActivityCreated(final Bundle savedInstanceState) {
154 super.onActivityCreated(savedInstanceState);
155 // Enable the options menu
156 setHasOptionsMenu(true);
158 final Bundle arguments = getArguments();
159 if (arguments != null) {
160 getLoaderManager().initLoader(LOADER, arguments, this);
168 public void onPause() {
177 public void onSaveInstanceState(final Bundle outState) {
178 super.onSaveInstanceState(outState);
179 outState.putAll(getArguments() != null ? getArguments() : new Bundle());
186 public void onCreateContextMenu(final ContextMenu menu, final View v,
187 final ContextMenuInfo menuInfo) {
188 super.onCreateContextMenu(menu, v, menuInfo);
190 // Get the position of the selected item
191 final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
192 // Create a new album
193 mAlbum = mAdapter.getItem(info.position - 1);
194 // Create a list of the album's songs
195 mAlbumList = MusicUtils.getSongListForAlbum(getActivity(), mAlbum.mAlbumId);
198 menu.add(GROUP_ID, FragmentMenuItems.PLAY_SELECTION, Menu.NONE,
199 getString(R.string.context_menu_play_selection));
201 // Add the album to the queue
202 menu.add(GROUP_ID, FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE,
203 getString(R.string.add_to_queue));
205 // Add the album to a playlist
206 final SubMenu subMenu = menu.addSubMenu(GROUP_ID, FragmentMenuItems.ADD_TO_PLAYLIST,
207 Menu.NONE, R.string.add_to_playlist);
208 MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, subMenu, false);
211 menu.add(GROUP_ID, FragmentMenuItems.DELETE, Menu.NONE,
212 getString(R.string.context_menu_delete));
219 public boolean onContextItemSelected(final MenuItem item) {
220 // Avoid leaking context menu selections
221 if (item.getGroupId() == GROUP_ID) {
222 switch (item.getItemId()) {
223 case FragmentMenuItems.PLAY_SELECTION:
224 MusicUtils.playAll(getActivity(), mAlbumList, 0, false);
226 case FragmentMenuItems.ADD_TO_QUEUE:
227 MusicUtils.addToQueue(getActivity(), mAlbumList);
229 case FragmentMenuItems.NEW_PLAYLIST:
230 CreateNewPlaylist.getInstance(mAlbumList).show(getFragmentManager(),
233 case FragmentMenuItems.PLAYLIST_SELECTED:
234 final long id = item.getIntent().getLongExtra("playlist", 0);
235 MusicUtils.addToPlaylist(getActivity(), mAlbumList, id);
237 case FragmentMenuItems.DELETE:
238 DeleteDialog.newInstance(mAlbum.mAlbumName, mAlbumList, null).show(
239 getFragmentManager(), "DeleteDialog");
246 return super.onContextItemSelected(item);
253 public void onItemClick(final AdapterView<?> parent, final View view, final int position,
258 mAlbum = mAdapter.getItem(position - 1);
259 NavUtils.openAlbumProfile(getActivity(), mAlbum.mAlbumName,
260 mAlbum.mArtistName, mAlbum.mAlbumId);
261 getActivity().finish();
268 public Loader<List<Album>> onCreateLoader(final int id, final Bundle args) {
269 return new ArtistAlbumLoader(getActivity(), args.getLong(Config.ID));
276 public void onLoadFinished(final Loader<List<Album>> loader, final List<Album> data) {
277 // Check for any errors
278 if (data.isEmpty()) {
284 // Return the correct count
285 mAdapter.setCount(data);
286 // Add the data to the adpater
287 for (final Album album : data) {
296 public void onLoaderReset(final Loader<List<Album>> loader) {
297 // Clear the data in the adapter
301 // Pause disk cache access to ensure smoother scrolling
302 private final ScrollableHeader mScrollableHeader = new ScrollableHeader() {
308 public void onScrollStateChanged(final AbsListView view, final int scrollState) {
309 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING
310 || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
311 mAdapter.setPauseDiskCache(true);
313 mAdapter.setPauseDiskCache(false);
314 mAdapter.notifyDataSetChanged();
320 * Restarts the loader.
322 public void refresh() {
323 // Scroll to the stop of the list before restarting the loader.
324 // Otherwise, if the user has scrolled enough to move the header, it
325 // becomes misplaced and needs to be reset.
326 mListView.setSelection(0);
327 // Wait a moment for the preference to change.
328 SystemClock.sleep(10);
329 mAdapter.notifyDataSetChanged();
330 getLoaderManager().restartLoader(LOADER, getArguments(), this);