OSDN Git Service

Improve context menus
[android-x86/packages-apps-Eleven.git] / src / com / andrew / apollo / ui / fragments / profile / FavoriteFragment.java
1 /*
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.
10  */
11
12 package com.andrew.apollo.ui.fragments.profile;
13
14 import android.app.Activity;
15 import android.database.Cursor;
16 import android.os.Bundle;
17 import android.os.SystemClock;
18 import android.support.v4.app.Fragment;
19 import android.support.v4.app.LoaderManager.LoaderCallbacks;
20 import android.support.v4.content.Loader;
21 import android.view.ContextMenu;
22 import android.view.ContextMenu.ContextMenuInfo;
23 import android.view.LayoutInflater;
24 import android.view.Menu;
25 import android.view.SubMenu;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.AdapterView;
29 import android.widget.AdapterView.AdapterContextMenuInfo;
30 import android.widget.AdapterView.OnItemClickListener;
31 import android.widget.ListView;
32 import android.widget.TextView;
33
34 import com.andrew.apollo.R;
35 import com.andrew.apollo.adapters.ProfileSongAdapter;
36 import com.andrew.apollo.loaders.FavoritesLoader;
37 import com.andrew.apollo.menu.CreateNewPlaylist;
38 import com.andrew.apollo.menu.DeleteDialog;
39 import com.andrew.apollo.menu.FragmentMenuItems;
40 import com.andrew.apollo.model.Song;
41 import com.andrew.apollo.provider.FavoritesStore;
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
48 import java.util.List;
49
50 /**
51  * This class is used to display all of the songs in {@link FavoritesStore
52  * }.
53  * 
54  * @author Andrew Neal (andrewdneal@gmail.com)
55  */
56 public class FavoriteFragment extends Fragment implements LoaderCallbacks<List<Song>>,
57         OnItemClickListener {
58
59     /**
60      * Used to keep context menu items from bleeding into other fragments
61      */
62     private static final int GROUP_ID = 6;
63
64     /**
65      * LoaderCallbacks identifier
66      */
67     private static final int LOADER = 0;
68
69     /**
70      * Fragment UI
71      */
72     private ViewGroup mRootView;
73
74     /**
75      * The adapter for the list
76      */
77     private ProfileSongAdapter mAdapter;
78
79     /**
80      * The list view
81      */
82     private ListView mListView;
83
84     /**
85      * Represents a song
86      */
87     private Song mSong;
88
89     /**
90      * Position of a context menu item
91      */
92     private int mSelectedPosition;
93
94     /**
95      * Id of a context menu item
96      */
97     private long mSelectedId;
98
99     /**
100      * Artist name used in the context menu
101      */
102     private String mArtistName;
103
104     /**
105      * Profile header
106      */
107     private ProfileTabCarousel mProfileTabCarousel;
108
109     /**
110      * Empty constructor as per the {@link Fragment} documentation
111      */
112     public FavoriteFragment() {
113     }
114
115     /**
116      * {@inheritDoc}
117      */
118     @Override
119     public void onAttach(final Activity activity) {
120         super.onAttach(activity);
121         mProfileTabCarousel = (ProfileTabCarousel)activity
122                 .findViewById(R.id.acivity_profile_base_tab_carousel);
123     }
124
125     /**
126      * {@inheritDoc}
127      */
128     @Override
129     public void onCreate(final Bundle savedInstanceState) {
130         super.onCreate(savedInstanceState);
131         // Create the adpater
132         mAdapter = new ProfileSongAdapter(getActivity(), R.layout.list_item_simple);
133     }
134
135     /**
136      * {@inheritDoc}
137      */
138     @Override
139     public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
140             final Bundle savedInstanceState) {
141         // The View for the fragment's UI
142         mRootView = (ViewGroup)inflater.inflate(R.layout.list_base, null);
143         // Initialize the list
144         mListView = (ListView)mRootView.findViewById(R.id.list_base);
145         // Set the data behind the list
146         mListView.setAdapter(mAdapter);
147         // Release any references to the recycled Views
148         mListView.setRecyclerListener(new RecycleHolder());
149         // Listen for ContextMenus to be created
150         mListView.setOnCreateContextMenuListener(this);
151         // Play the selected song
152         mListView.setOnItemClickListener(this);
153         // To help make scrolling smooth
154         mListView.setOnScrollListener(new VerticalScrollListener(null, mProfileTabCarousel, 0));
155         // Remove the scrollbars and padding for the fast scroll
156         mListView.setVerticalScrollBarEnabled(false);
157         mListView.setFastScrollEnabled(false);
158         mListView.setPadding(0, 0, 0, 0);
159         return mRootView;
160     }
161
162     /**
163      * {@inheritDoc}
164      */
165     @Override
166     public void onActivityCreated(final Bundle savedInstanceState) {
167         super.onActivityCreated(savedInstanceState);
168         // Enable the options menu
169         setHasOptionsMenu(true);
170         // Start the loader
171         getLoaderManager().initLoader(LOADER, null, this);
172     }
173
174     /**
175      * {@inheritDoc}
176      */
177     @Override
178     public void onCreateContextMenu(final ContextMenu menu, final View v,
179             final ContextMenuInfo menuInfo) {
180         super.onCreateContextMenu(menu, v, menuInfo);
181         // Get the position of the selected item
182         final AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
183         mSelectedPosition = info.position - 1;
184         // Creat a new song
185         mSong = mAdapter.getItem(mSelectedPosition);
186         mSelectedId = mSong.mSongId;
187         mArtistName = mSong.mArtistName;
188
189         // Play the song
190         menu.add(GROUP_ID, FragmentMenuItems.PLAY_SELECTION, Menu.NONE,
191                 getString(R.string.context_menu_play_selection));
192
193         // Play next
194         menu.add(GROUP_ID, FragmentMenuItems.PLAY_NEXT, Menu.NONE,
195                 getString(R.string.context_menu_play_next));
196
197         // Add the song to the queue
198         menu.add(GROUP_ID, FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE,
199                 getString(R.string.add_to_queue));
200
201         // Add the song to a playlist
202         final SubMenu subMenu = menu.addSubMenu(GROUP_ID, FragmentMenuItems.ADD_TO_PLAYLIST,
203                 Menu.NONE, R.string.add_to_playlist);
204         MusicUtils.makePlaylistMenu(getActivity(), GROUP_ID, subMenu, false);
205
206         // View more content by the song artist
207         menu.add(GROUP_ID, FragmentMenuItems.MORE_BY_ARTIST, Menu.NONE,
208                 getString(R.string.context_menu_more_by_artist));
209
210         // Make the song a ringtone
211         menu.add(GROUP_ID, FragmentMenuItems.USE_AS_RINGTONE, Menu.NONE,
212                 getString(R.string.context_menu_use_as_ringtone));
213
214         // Remove from favorites
215         menu.add(GROUP_ID, FragmentMenuItems.REMOVE_FROM_FAVORITES, Menu.NONE,
216                 getString(R.string.remove_from_favorites));
217
218         // Delete the song
219         menu.add(GROUP_ID, FragmentMenuItems.DELETE, Menu.NONE,
220                 getString(R.string.context_menu_delete));
221     }
222
223     @Override
224     public boolean onContextItemSelected(final android.view.MenuItem item) {
225         if (item.getGroupId() == GROUP_ID) {
226             switch (item.getItemId()) {
227                 case FragmentMenuItems.PLAY_SELECTION:
228                     MusicUtils.playAll(getActivity(), new long[] {
229                         mSelectedId
230                     }, 0, false);
231                     return true;
232                 case FragmentMenuItems.PLAY_NEXT:
233                     MusicUtils.playNext(new long[] {
234                         mSelectedId
235                     });
236                     return true;
237                 case FragmentMenuItems.ADD_TO_QUEUE:
238                     MusicUtils.addToQueue(getActivity(), new long[] {
239                         mSelectedId
240                     });
241                     return true;
242                 case FragmentMenuItems.NEW_PLAYLIST:
243                     CreateNewPlaylist.getInstance(new long[] {
244                         mSelectedId
245                     }).show(getFragmentManager(), "CreatePlaylist");
246                     return true;
247                 case FragmentMenuItems.PLAYLIST_SELECTED:
248                     final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0);
249                     MusicUtils.addToPlaylist(getActivity(), new long[] {
250                         mSelectedId
251                     }, mPlaylistId);
252                     return true;
253                 case FragmentMenuItems.MORE_BY_ARTIST:
254                     NavUtils.openArtistProfile(getActivity(), mArtistName);
255                     return true;
256                 case FragmentMenuItems.USE_AS_RINGTONE:
257                     MusicUtils.setRingtone(getActivity(), mSelectedId);
258                     return true;
259                 case FragmentMenuItems.REMOVE_FROM_FAVORITES:
260                     FavoritesStore.getInstance(getActivity()).removeItem(mSelectedId);
261                     getLoaderManager().restartLoader(LOADER, null, this);
262                     return true;
263                 case FragmentMenuItems.DELETE:
264                     DeleteDialog.newInstance(mSong.mSongName, new long[] {
265                         mSelectedId
266                     }, null).show(getFragmentManager(), "DeleteDialog");
267                     SystemClock.sleep(10);
268                     mAdapter.notifyDataSetChanged();
269                     getLoaderManager().restartLoader(LOADER, null, this);
270                     return true;
271                 default:
272                     break;
273             }
274         }
275         return super.onContextItemSelected(item);
276     }
277
278     /**
279      * {@inheritDoc}
280      */
281     @Override
282     public void onItemClick(final AdapterView<?> parent, final View view, final int position,
283             final long id) {
284         if (position == 0) {
285             return;
286         }
287         Cursor cursor = FavoritesLoader.makeFavoritesCursor(getActivity());
288         final long[] list = MusicUtils.getSongListForCursor(cursor);
289         MusicUtils.playAll(getActivity(), list, position - 1, false);
290         cursor.close();
291         cursor = null;
292     }
293
294     /**
295      * {@inheritDoc}
296      */
297     @Override
298     public Loader<List<Song>> onCreateLoader(final int id, final Bundle args) {
299         return new FavoritesLoader(getActivity());
300     }
301
302     /**
303      * {@inheritDoc}
304      */
305     @Override
306     public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) {
307         // Check for any errors
308         if (data.isEmpty()) {
309             // Set the empty text
310             final TextView empty = (TextView)mRootView.findViewById(R.id.empty);
311             empty.setText(getString(R.string.empty_favorite));
312             mListView.setEmptyView(empty);
313             return;
314         }
315
316         // Start fresh
317         mAdapter.unload();
318         // Return the correct count
319         mAdapter.setCount(data);
320         // Add the data to the adpater
321         for (final Song song : data) {
322             mAdapter.add(song);
323         }
324     }
325
326     /**
327      * {@inheritDoc}
328      */
329     @Override
330     public void onLoaderReset(final Loader<List<Song>> loader) {
331         // Clear the data in the adapter
332         mAdapter.unload();
333     }
334
335 }