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;
14 import android.os.Bundle;
15 import android.os.SystemClock;
16 import android.support.v4.app.LoaderManager.LoaderCallbacks;
17 import android.support.v4.content.Loader;
18 import android.view.LayoutInflater;
19 import android.view.View;
20 import android.view.ViewGroup;
21 import android.widget.AbsListView;
22 import android.widget.AbsListView.OnScrollListener;
23 import android.widget.AdapterView;
24 import android.widget.AdapterView.OnItemClickListener;
25 import android.widget.GridView;
27 import com.cyngn.eleven.MusicStateListener;
28 import com.cyngn.eleven.R;
29 import com.cyngn.eleven.adapters.AlbumAdapter;
30 import com.cyngn.eleven.adapters.PagerAdapter;
31 import com.cyngn.eleven.loaders.AlbumLoader;
32 import com.cyngn.eleven.model.Album;
33 import com.cyngn.eleven.recycler.RecycleHolder;
34 import com.cyngn.eleven.sectionadapter.SectionCreator;
35 import com.cyngn.eleven.sectionadapter.SectionListContainer;
36 import com.cyngn.eleven.ui.activities.BaseActivity;
37 import com.cyngn.eleven.ui.fragments.phone.MusicBrowserFragment;
38 import com.cyngn.eleven.utils.AlbumPopupMenuHelper;
39 import com.cyngn.eleven.utils.ApolloUtils;
40 import com.cyngn.eleven.utils.MusicUtils;
41 import com.cyngn.eleven.utils.NavUtils;
42 import com.cyngn.eleven.utils.PopupMenuHelper;
43 import com.cyngn.eleven.widgets.IPopupMenuCallback;
44 import com.cyngn.eleven.widgets.LoadingEmptyContainer;
45 import com.viewpagerindicator.TitlePageIndicator;
48 * This class is used to display all of the albums on a user's device.
50 * @author Andrew Neal (andrewdneal@gmail.com)
52 public class AlbumFragment extends MusicBrowserFragment implements
53 LoaderCallbacks<SectionListContainer<Album>>, OnScrollListener,
54 OnItemClickListener, MusicStateListener {
57 * Grid view column count. ONE - list, TWO - normal grid, FOUR - landscape
59 private static final int TWO = 2, FOUR = 4;
64 private ViewGroup mRootView;
67 * The adapter for the grid
69 private AlbumAdapter mAdapter;
74 private GridView mGridView;
79 private PopupMenuHelper mPopupMenuHelper;
82 * This holds the loading progress bar as well as the no results message
84 private LoadingEmptyContainer mLoadingEmptyContainer;
87 public int getLoaderId() {
88 return PagerAdapter.MusicFragments.ALBUM.ordinal();
95 public void onCreate(final Bundle savedInstanceState) {
96 super.onCreate(savedInstanceState);
98 mPopupMenuHelper = new AlbumPopupMenuHelper(getActivity(), getFragmentManager()) {
99 public Album getAlbum(int position) {
100 return mAdapter.getItem(position);
104 int layout = R.layout.grid_items_normal;
106 mAdapter = new AlbumAdapter(getActivity(), layout);
107 mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
109 public void onPopupMenuClicked(View v, int position) {
110 mPopupMenuHelper.showPopupMenu(v, position);
119 public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
120 final Bundle savedInstanceState) {
121 mRootView = (ViewGroup)inflater.inflate(R.layout.grid_base, null);
124 // Register the music status listener
125 ((BaseActivity)getActivity()).setMusicStateListenerListener(this);
134 public void onActivityCreated(final Bundle savedInstanceState) {
135 super.onActivityCreated(savedInstanceState);
136 // Enable the options menu
137 setHasOptionsMenu(true);
139 initLoader(null, this);
143 public void onDestroyView() {
144 super.onDestroyView();
146 ((BaseActivity)getActivity()).removeMusicStateListenerListener(this);
154 public void onPause() {
163 public void onScrollStateChanged(final AbsListView view, final int scrollState) {
164 // Pause disk cache access to ensure smoother scrolling
165 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
166 mAdapter.setPauseDiskCache(true);
168 mAdapter.setPauseDiskCache(false);
169 mAdapter.notifyDataSetChanged();
177 public void onItemClick(final AdapterView<?> parent, final View view, final int position,
179 Album album = mAdapter.getItem(position);
180 NavUtils.openAlbumProfile(getActivity(), album.mAlbumName, album.mArtistName, album.mAlbumId);
187 public Loader<SectionListContainer<Album>> onCreateLoader(final int id, final Bundle args) {
188 mLoadingEmptyContainer.showLoading();
189 // if we ever decide to add section headers for grid items, we can pass a compartor
191 return new SectionCreator<Album>(getActivity(), new AlbumLoader(getActivity()), null);
198 public void onLoadFinished(final Loader<SectionListContainer<Album>> loader,
199 final SectionListContainer<Album> data) {
200 // Check for any errors
201 if (data.mListResults.isEmpty()) {
202 mLoadingEmptyContainer.showNoResults();
206 mAdapter.setData(data.mListResults);
213 public void onLoaderReset(final Loader<SectionListContainer<Album>> loader) {
214 // Clear the data in the adapter
219 * Scrolls the list to the currently playing album when the user touches the
220 * header in the {@link TitlePageIndicator}.
222 public void scrollToCurrentAlbum() {
223 final int currentAlbumPosition = getItemPositionByAlbum();
225 if (currentAlbumPosition != 0) {
226 mGridView.setSelection(currentAlbumPosition);
231 * @return The position of an item in the list or grid based on the id of
232 * the currently playing album.
234 private int getItemPositionByAlbum() {
235 final long albumId = MusicUtils.getCurrentAlbumId();
236 if (mAdapter == null) {
240 int position = mAdapter.getItemPosition(albumId);
242 // if for some reason we don't find the item, just jump to the top
251 * Restarts the loader.
253 public void refresh() {
254 // Wait a moment for the preference to change.
255 SystemClock.sleep(10);
263 public void onScroll(final AbsListView view, final int firstVisibleItem,
264 final int visibleItemCount, final int totalItemCount) {
272 public void restartLoader() {
273 // Update the list when the user deletes any items
274 restartLoader(null, this);
281 public void onMetaChanged() {
286 public void onPlaylistChanged() {
291 * Sets up various helpers for both the list and grid
293 * @param list The list or grid
295 private void initAbsListView(final AbsListView list) {
296 // Release any references to the recycled Views
297 list.setRecyclerListener(new RecycleHolder());
298 // Show the albums and songs from the selected artist
299 list.setOnItemClickListener(this);
300 // To help make scrolling smooth
301 list.setOnScrollListener(this);
305 * Sets up the grid view
307 private void initGridView() {
308 int columns = ApolloUtils.isLandscape(getActivity()) ? FOUR : TWO;
309 mAdapter.setNumColumns(columns);
310 // Initialize the grid
311 mGridView = (GridView)mRootView.findViewById(R.id.grid_base);
312 // Set the data behind the grid
313 mGridView.setAdapter(mAdapter);
314 // Set up the helpers
315 initAbsListView(mGridView);
316 mGridView.setNumColumns(columns);
319 mLoadingEmptyContainer = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
320 mGridView.setEmptyView(mLoadingEmptyContainer);