2 * Copyright (C) 2012 Andrew Neal
3 * Copyright (C) 2014 The CyanogenMod Project
4 * Licensed under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with the
6 * License. You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
8 * or agreed to in writing, software distributed under the License is
9 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
10 * KIND, either express or implied. See the License for the specific language
11 * governing permissions and limitations under the License.
14 package org.lineageos.eleven.ui.fragments;
16 import android.os.Bundle;
17 import android.os.SystemClock;
18 import android.support.v4.app.LoaderManager.LoaderCallbacks;
19 import android.support.v4.content.Loader;
20 import android.view.LayoutInflater;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.widget.AbsListView;
24 import android.widget.AbsListView.OnScrollListener;
25 import android.widget.AdapterView;
26 import android.widget.AdapterView.OnItemClickListener;
27 import android.widget.GridView;
29 import org.lineageos.eleven.MusicStateListener;
30 import org.lineageos.eleven.R;
31 import org.lineageos.eleven.adapters.AlbumAdapter;
32 import org.lineageos.eleven.adapters.PagerAdapter;
33 import org.lineageos.eleven.loaders.AlbumLoader;
34 import org.lineageos.eleven.model.Album;
35 import org.lineageos.eleven.recycler.RecycleHolder;
36 import org.lineageos.eleven.sectionadapter.SectionCreator;
37 import org.lineageos.eleven.sectionadapter.SectionListContainer;
38 import org.lineageos.eleven.ui.activities.BaseActivity;
39 import org.lineageos.eleven.ui.fragments.phone.MusicBrowserFragment;
40 import org.lineageos.eleven.utils.AlbumPopupMenuHelper;
41 import org.lineageos.eleven.utils.ElevenUtils;
42 import org.lineageos.eleven.utils.MusicUtils;
43 import org.lineageos.eleven.utils.NavUtils;
44 import org.lineageos.eleven.utils.PopupMenuHelper;
45 import org.lineageos.eleven.widgets.IPopupMenuCallback;
46 import org.lineageos.eleven.widgets.LoadingEmptyContainer;
49 * This class is used to display all of the albums on a user's device.
51 * @author Andrew Neal (andrewdneal@gmail.com)
53 public class AlbumFragment extends MusicBrowserFragment implements
54 LoaderCallbacks<SectionListContainer<Album>>, OnScrollListener,
55 OnItemClickListener, MusicStateListener {
58 * Grid view column count. ONE - list, TWO - normal grid, FOUR - landscape
60 private static final int TWO = 2, FOUR = 4;
65 private ViewGroup mRootView;
68 * The adapter for the grid
70 private AlbumAdapter mAdapter;
75 private GridView mGridView;
80 private PopupMenuHelper mPopupMenuHelper;
83 * This holds the loading progress bar as well as the no results message
85 private LoadingEmptyContainer mLoadingEmptyContainer;
88 public int getLoaderId() {
89 return PagerAdapter.MusicFragments.ALBUM.ordinal();
96 public void onCreate(final Bundle savedInstanceState) {
97 super.onCreate(savedInstanceState);
99 mPopupMenuHelper = new AlbumPopupMenuHelper(getActivity(), getFragmentManager()) {
100 public Album getAlbum(int position) {
101 return mAdapter.getItem(position);
105 int layout = R.layout.grid_items_normal;
107 mAdapter = new AlbumAdapter(getActivity(), layout);
108 mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
110 public void onPopupMenuClicked(View v, int position) {
111 mPopupMenuHelper.showPopupMenu(v, position);
120 public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
121 final Bundle savedInstanceState) {
122 mRootView = (ViewGroup)inflater.inflate(R.layout.grid_base, null);
125 // Register the music status listener
126 ((BaseActivity)getActivity()).setMusicStateListenerListener(this);
135 public void onActivityCreated(final Bundle savedInstanceState) {
136 super.onActivityCreated(savedInstanceState);
137 // Enable the options menu
138 setHasOptionsMenu(true);
140 initLoader(null, this);
144 public void onDestroyView() {
145 super.onDestroyView();
147 ((BaseActivity)getActivity()).removeMusicStateListenerListener(this);
155 public void onPause() {
164 public void onScrollStateChanged(final AbsListView view, final int scrollState) {
165 // Pause disk cache access to ensure smoother scrolling
166 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
167 mAdapter.setPauseDiskCache(true);
169 mAdapter.setPauseDiskCache(false);
170 mAdapter.notifyDataSetChanged();
178 public void onItemClick(final AdapterView<?> parent, final View view, final int position,
180 Album album = mAdapter.getItem(position);
181 NavUtils.openAlbumProfile(getActivity(), album.mAlbumName, album.mArtistName, album.mAlbumId);
188 public Loader<SectionListContainer<Album>> onCreateLoader(final int id, final Bundle args) {
189 mLoadingEmptyContainer.showLoading();
190 // if we ever decide to add section headers for grid items, we can pass a compartor
192 return new SectionCreator<>(getActivity(), new AlbumLoader(getActivity()), null);
199 public void onLoadFinished(final Loader<SectionListContainer<Album>> loader,
200 final SectionListContainer<Album> data) {
201 if (data.mListResults.isEmpty()) {
203 mLoadingEmptyContainer.showNoResults();
207 mAdapter.setData(data.mListResults);
214 public void onLoaderReset(final Loader<SectionListContainer<Album>> loader) {
215 // Clear the data in the adapter
220 * Scrolls the list to the currently playing album when the user touches the
221 * header in the {@link TitlePageIndicator}.
223 public void scrollToCurrentAlbum() {
224 final int currentAlbumPosition = getItemPositionByAlbum();
226 if (currentAlbumPosition != 0) {
227 mGridView.setSelection(currentAlbumPosition);
232 * @return The position of an item in the list or grid based on the id of
233 * the currently playing album.
235 private int getItemPositionByAlbum() {
236 final long albumId = MusicUtils.getCurrentAlbumId();
237 if (mAdapter == null) {
241 int position = mAdapter.getItemPosition(albumId);
243 // if for some reason we don't find the item, just jump to the top
252 * Restarts the loader.
254 public void refresh() {
255 // Wait a moment for the preference to change.
256 SystemClock.sleep(10);
264 public void onScroll(final AbsListView view, final int firstVisibleItem,
265 final int visibleItemCount, final int totalItemCount) {
273 public void restartLoader() {
274 // Update the list when the user deletes any items
275 restartLoader(null, this);
282 public void onMetaChanged() {
287 public void onPlaylistChanged() {
292 * Sets up various helpers for both the list and grid
294 * @param list The list or grid
296 private void initAbsListView(final AbsListView list) {
297 // Release any references to the recycled Views
298 list.setRecyclerListener(new RecycleHolder());
299 // Show the albums and songs from the selected artist
300 list.setOnItemClickListener(this);
301 // To help make scrolling smooth
302 list.setOnScrollListener(this);
306 * Sets up the grid view
308 private void initGridView() {
309 int columns = ElevenUtils.isLandscape(getActivity()) ? FOUR : TWO;
310 mAdapter.setNumColumns(columns);
311 // Initialize the grid
312 mGridView = (GridView)mRootView.findViewById(R.id.grid_base);
313 // Set the data behind the grid
314 mGridView.setAdapter(mAdapter);
315 // Set up the helpers
316 initAbsListView(mGridView);
317 mGridView.setNumColumns(columns);
320 mLoadingEmptyContainer = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
321 mGridView.setEmptyView(mLoadingEmptyContainer);