OSDN Git Service

100c55a2bab9839ddbe19843fe9ce04379d47cb2
[android-x86/packages-apps-Eleven.git] / src / com / cyanogenmod / eleven / ui / fragments / ArtistFragment.java
1 /*
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.
12  */
13
14 package com.cyanogenmod.eleven.ui.fragments;
15
16 import android.content.Context;
17 import android.os.Bundle;
18 import android.os.SystemClock;
19 import android.support.v4.app.Fragment;
20 import android.support.v4.app.LoaderManager.LoaderCallbacks;
21 import android.support.v4.content.Loader;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.widget.AbsListView;
26 import android.widget.AbsListView.OnScrollListener;
27 import android.widget.AdapterView;
28 import android.widget.AdapterView.OnItemClickListener;
29 import android.widget.ListView;
30
31 import com.cyanogenmod.eleven.MusicStateListener;
32 import com.cyanogenmod.eleven.R;
33 import com.cyanogenmod.eleven.adapters.ArtistAdapter;
34 import com.cyanogenmod.eleven.adapters.PagerAdapter;
35 import com.cyanogenmod.eleven.loaders.ArtistLoader;
36 import com.cyanogenmod.eleven.model.Artist;
37 import com.cyanogenmod.eleven.recycler.RecycleHolder;
38 import com.cyanogenmod.eleven.sectionadapter.SectionAdapter;
39 import com.cyanogenmod.eleven.sectionadapter.SectionCreator;
40 import com.cyanogenmod.eleven.sectionadapter.SectionListContainer;
41 import com.cyanogenmod.eleven.ui.activities.BaseActivity;
42 import com.cyanogenmod.eleven.ui.fragments.phone.MusicBrowserFragment;
43 import com.cyanogenmod.eleven.utils.ArtistPopupMenuHelper;
44 import com.cyanogenmod.eleven.utils.MusicUtils;
45 import com.cyanogenmod.eleven.utils.NavUtils;
46 import com.cyanogenmod.eleven.utils.PopupMenuHelper;
47 import com.cyanogenmod.eleven.utils.SectionCreatorUtils;
48 import com.cyanogenmod.eleven.utils.SectionCreatorUtils.IItemCompare;
49 import com.cyanogenmod.eleven.widgets.IPopupMenuCallback;
50 import com.cyanogenmod.eleven.widgets.LoadingEmptyContainer;
51
52 /**
53  * This class is used to display all of the artists on a user's device.
54  *
55  * @author Andrew Neal (andrewdneal@gmail.com)
56  */
57 public class ArtistFragment extends MusicBrowserFragment implements
58         LoaderCallbacks<SectionListContainer<Artist>>,
59         OnScrollListener, OnItemClickListener, MusicStateListener {
60
61     /**
62      * Fragment UI
63      */
64     private ViewGroup mRootView;
65
66     /**
67      * The adapter for the grid
68      */
69     private SectionAdapter<Artist, ArtistAdapter> mAdapter;
70
71     /**
72      * The list view
73      */
74     private ListView mListView;
75
76     /**
77      * Pop up menu helper
78      */
79     private PopupMenuHelper mPopupMenuHelper;
80
81     /**
82      * Loading container and no results container
83      */
84     private LoadingEmptyContainer mLoadingEmptyContainer;
85
86     /**
87      * Empty constructor as per the {@link Fragment} documentation
88      */
89     public ArtistFragment() {
90     }
91
92     @Override
93     public int getLoaderId() {
94         return PagerAdapter.MusicFragments.ARTIST.ordinal();
95     }
96
97     /**
98      * {@inheritDoc}
99      */
100     @Override
101     public void onCreate(final Bundle savedInstanceState) {
102         super.onCreate(savedInstanceState);
103
104         mPopupMenuHelper = new ArtistPopupMenuHelper(getActivity(), getFragmentManager()) {
105             @Override
106             public Artist getArtist(int position) {
107                 return mAdapter.getTItem(position);
108             }
109         };
110
111         // Create the adapter
112         final int layout = R.layout.list_item_normal;
113         ArtistAdapter adapter = new ArtistAdapter(getActivity(), layout);
114         mAdapter = new SectionAdapter<Artist, ArtistAdapter>(getActivity(), adapter);
115         mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
116             @Override
117             public void onPopupMenuClicked(View v, int position) {
118                 mPopupMenuHelper.showPopupMenu(v, position);
119             }
120         });
121     }
122
123     /**
124      * {@inheritDoc}
125      */
126     @Override
127     public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
128             final Bundle savedInstanceState) {
129         // The View for the fragment's UI
130         mRootView = (ViewGroup)inflater.inflate(R.layout.list_base, null);
131         initListView();
132
133         // Register the music status listener
134         ((BaseActivity)getActivity()).setMusicStateListenerListener(this);
135
136         return mRootView;
137     }
138
139     @Override
140     public void onDestroyView() {
141         super.onDestroyView();
142
143         ((BaseActivity)getActivity()).removeMusicStateListenerListener(this);
144     }
145
146
147     /**
148      * {@inheritDoc}
149      */
150     @Override
151     public void onActivityCreated(final Bundle savedInstanceState) {
152         super.onActivityCreated(savedInstanceState);
153         // Enable the options menu
154         setHasOptionsMenu(true);
155         // Start the loader
156         initLoader(null, this);
157     }
158
159     /**
160      * {@inheritDoc}
161      */
162     @Override
163     public void onPause() {
164         super.onPause();
165         mAdapter.flush();
166     }
167
168     /**
169      * {@inheritDoc}
170      */
171     @Override
172     public void onScrollStateChanged(final AbsListView view, final int scrollState) {
173         // Pause disk cache access to ensure smoother scrolling
174         if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
175             mAdapter.getUnderlyingAdapter().setPauseDiskCache(true);
176         } else {
177             mAdapter.getUnderlyingAdapter().setPauseDiskCache(false);
178             mAdapter.notifyDataSetChanged();
179         }
180     }
181
182     /**
183      * {@inheritDoc}
184      */
185     @Override
186     public void onItemClick(final AdapterView<?> parent, final View view, final int position,
187             final long id) {
188         Artist artist = mAdapter.getTItem(position);
189         NavUtils.openArtistProfile(getActivity(), artist.mArtistName);
190     }
191
192     /**
193      * {@inheritDoc}
194      */
195     @Override
196     public Loader<SectionListContainer<Artist>> onCreateLoader(final int id, final Bundle args) {
197         mLoadingEmptyContainer.showLoading();
198         final Context context = getActivity();
199         IItemCompare<Artist> comparator = SectionCreatorUtils.createArtistComparison(context);
200         return new SectionCreator<Artist>(getActivity(), new ArtistLoader(context), comparator);
201     }
202
203     /**
204      * {@inheritDoc}
205      */
206     @Override
207     public void onLoadFinished(final Loader<SectionListContainer<Artist>> loader,
208                                final SectionListContainer<Artist> data) {
209         if (data.mListResults.isEmpty()) {
210             mAdapter.unload();
211             mLoadingEmptyContainer.showNoResults();
212             return;
213         }
214
215         mAdapter.setData(data);
216     }
217
218     /**
219      * {@inheritDoc}
220      */
221     @Override
222     public void onLoaderReset(final Loader<SectionListContainer<Artist>> loader) {
223         // Clear the data in the adapter
224         mAdapter.unload();
225     }
226
227     /**
228      * Scrolls the list to the currently playing artist when the user touches
229      * the header in the {@link TitlePageIndicator}.
230      */
231     public void scrollToCurrentArtist() {
232         final int currentArtistPosition = getItemPositionByArtist();
233
234         if (currentArtistPosition != 0) {
235             mListView.setSelection(currentArtistPosition);
236         }
237     }
238
239     /**
240      * @return The position of an item in the list or grid based on the name of
241      *         the currently playing artist.
242      */
243     private int getItemPositionByArtist() {
244         final long artistId = MusicUtils.getCurrentArtistId();
245         if (mAdapter == null) {
246             return 0;
247         }
248
249         int position = mAdapter.getItemPosition(artistId);
250
251         // if for some reason we don't find the item, just jump to the top
252         if (position < 0) {
253             return 0;
254         }
255
256         return position;
257     }
258
259     /**
260      * Restarts the loader.
261      */
262     public void refresh() {
263         // Wait a moment for the preference to change.
264         SystemClock.sleep(10);
265         restartLoader();
266     }
267
268     /**
269      * {@inheritDoc}
270      */
271     @Override
272     public void onScroll(final AbsListView view, final int firstVisibleItem,
273             final int visibleItemCount, final int totalItemCount) {
274         // Nothing to do
275     }
276
277     /**
278      * {@inheritDoc}
279      */
280     @Override
281     public void restartLoader() {
282         // Update the list when the user deletes any items
283         restartLoader(null, this);
284     }
285
286     /**
287      * {@inheritDoc}
288      */
289     @Override
290     public void onMetaChanged() {
291         // Nothing to do
292     }
293
294     @Override
295     public void onPlaylistChanged() {
296         // Nothing to do
297     }
298
299     /**
300      * Sets up various helpers for both the list and grid
301      *
302      * @param list The list or grid
303      */
304     private void initAbsListView(final AbsListView list) {
305         // Release any references to the recycled Views
306         list.setRecyclerListener(new RecycleHolder());
307         // Show the albums and songs from the selected artist
308         list.setOnItemClickListener(this);
309         // To help make scrolling smooth
310         list.setOnScrollListener(this);
311     }
312
313     /**
314      * Sets up the list view
315      */
316     private void initListView() {
317         // Initialize the grid
318         mListView = (ListView)mRootView.findViewById(R.id.list_base);
319         // Set the data behind the list
320         mListView.setAdapter(mAdapter);
321         // set the loading and empty view container
322         mLoadingEmptyContainer = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
323         mListView.setEmptyView(mLoadingEmptyContainer);
324         // Set up the helpers
325         initAbsListView(mListView);
326     }
327 }