OSDN Git Service

Eleven: Add the context menu items to the 2nd layer
[android-x86/packages-apps-Eleven.git] / src / com / cyngn / eleven / ui / fragments / profile / BasicSongFragment.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.cyngn.eleven.ui.fragments.profile;
13
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.LayoutInflater;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.widget.AbsListView;
24 import android.widget.AdapterView;
25 import android.widget.AdapterView.OnItemClickListener;
26 import android.widget.ListView;
27
28 import com.cyngn.eleven.MusicStateListener;
29 import com.cyngn.eleven.R;
30 import com.cyngn.eleven.adapters.SongAdapter;
31 import com.cyngn.eleven.model.Song;
32 import com.cyngn.eleven.recycler.RecycleHolder;
33 import com.cyngn.eleven.sectionadapter.SectionAdapter;
34 import com.cyngn.eleven.sectionadapter.SectionListContainer;
35 import com.cyngn.eleven.ui.activities.BaseActivity;
36 import com.cyngn.eleven.utils.PopupMenuHelper;
37 import com.cyngn.eleven.utils.SongPopupMenuHelper;
38 import com.cyngn.eleven.widgets.IPopupMenuCallback;
39 import com.cyngn.eleven.widgets.NoResultsContainer;
40
41 import java.util.TreeSet;
42
43 /**
44  * This class is used to display all of the songs
45  *
46  * @author Andrew Neal (andrewdneal@gmail.com)
47  */
48 public abstract class BasicSongFragment extends Fragment implements
49         LoaderCallbacks<SectionListContainer<Song>>, OnItemClickListener, MusicStateListener {
50
51     /**
52      * Fragment UI
53      */
54     protected ViewGroup mRootView;
55
56     /**
57      * The adapter for the list
58      */
59     protected SectionAdapter<Song, SongAdapter> mAdapter;
60
61     /**
62      * The list view
63      */
64     protected ListView mListView;
65
66     /**
67      * Pop up menu helper
68      */
69     private PopupMenuHelper mPopupMenuHelper;
70
71     /**
72      * Empty constructor as per the {@link Fragment} documentation
73      */
74     public BasicSongFragment() {
75     }
76
77     /**
78      * {@inheritDoc}
79      */
80     @Override
81     public void onAttach(final Activity activity) {
82         super.onAttach(activity);
83         // Register the music status listener
84         ((BaseActivity)activity).setMusicStateListenerListener(this);
85     }
86
87     /**
88      * {@inheritDoc}
89      */
90     @Override
91     public void onCreate(final Bundle savedInstanceState) {
92         super.onCreate(savedInstanceState);
93         mPopupMenuHelper = new SongPopupMenuHelper(getActivity(), getFragmentManager()) {
94             @Override
95             public Song getSong(int position) {
96                 return mAdapter.getTItem(position);
97             }
98
99             @Override
100             protected void updateMenuIds(PopupMenuType type, TreeSet<Integer> set) {
101                 super.updateMenuIds(type, set);
102                 BasicSongFragment.this.updateMenuIds(set);
103             }
104         };
105
106         // Create the adapter
107         mAdapter = createAdapter();
108         mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
109             @Override
110             public void onPopupMenuClicked(View v, int position) {
111                 mPopupMenuHelper.showPopupMenu(v, position);
112             }
113         });
114     }
115
116     protected void updateMenuIds(TreeSet<Integer> set) {
117         // do nothing - let subclasses override
118     }
119
120     /**
121      * {@inheritDoc}
122      */
123     @Override
124     public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
125                              final Bundle savedInstanceState) {
126         // The View for the fragment's UI
127         mRootView = (ViewGroup) inflater.inflate(R.layout.list_base, null);
128         // Initialize the list
129         mListView = (ListView) mRootView.findViewById(R.id.list_base);
130         // Set the data behind the list
131         mListView.setAdapter(mAdapter);
132         // Release any references to the recycled Views
133         mListView.setRecyclerListener(new RecycleHolder());
134         // Play the selected song
135         mListView.setOnItemClickListener(this);
136         // To help make scrolling smooth
137         mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
138             @Override
139             public void onScrollStateChanged(AbsListView view, int scrollState) {
140                 // Pause disk cache access to ensure smoother scrolling
141                 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING
142                         || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
143                     mAdapter.getUnderlyingAdapter().setPauseDiskCache(true);
144                 } else {
145                     mAdapter.getUnderlyingAdapter().setPauseDiskCache(false);
146                     mAdapter.notifyDataSetChanged();
147                 }
148             }
149
150             @Override
151             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
152
153             }
154         });
155
156         return mRootView;
157     }
158
159     /**
160      * This allows subclasses to customize the look and feel of the no results container
161      * @param empty NoResultsContainer class
162      */
163     public void setupNoResultsContainer(final NoResultsContainer empty) {
164         // do nothing
165     }
166
167     /**
168      * {@inheritDoc}
169      */
170     @Override
171     public void onActivityCreated(final Bundle savedInstanceState) {
172         super.onActivityCreated(savedInstanceState);
173         // Start the loader
174         getLoaderManager().initLoader(getLoaderId(), null, this);
175     }
176
177     /**
178      * {@inheritDoc}
179      */
180     @Override
181     public void onItemClick(final AdapterView<?> parent, final View view, final int position,
182                             final long id) {
183         playAll(position);
184     }
185
186     /**
187      * {@inheritDoc}
188      */
189     @Override
190     public void onLoadFinished(final Loader<SectionListContainer<Song>> loader,
191                                final SectionListContainer<Song> data) {
192         // Check for any errors
193         if (data.mListResults.isEmpty()) {
194             // Set the empty text
195             final NoResultsContainer empty =
196                     (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
197             // Setup the container strings
198             setupNoResultsContainer(empty);
199             // set the empty view into the list view
200             mListView.setEmptyView(empty);
201             return;
202         }
203
204         // Start fresh
205         mAdapter.setData(data);
206     }
207
208     /**
209      * Restarts the loader.
210      */
211     public void refresh() {
212         // Wait a moment for the preference to change.
213         SystemClock.sleep(10);
214         getLoaderManager().restartLoader(getLoaderId(), null, this);
215     }
216
217     /**
218      * {@inheritDoc}
219      */
220     @Override
221     public void restartLoader() {
222         // Update the list when the user deletes any items
223         getLoaderManager().restartLoader(getLoaderId(), null, this);
224     }
225
226     /**
227      * {@inheritDoc}
228      */
229     @Override
230     public void onLoaderReset(final Loader<SectionListContainer<Song>> loader) {
231         // Clear the data in the adapter
232         mAdapter.unload();
233     }
234
235     /**
236      * If the subclasses want to use a customized SongAdapter they can override this method
237      * @return the Song adapter
238      */
239     protected SectionAdapter<Song, SongAdapter> createAdapter() {
240         return new SectionAdapter(getActivity(),
241                 new SongAdapter(
242                     getActivity(),
243                     R.layout.list_item_normal
244                 )
245         );
246     }
247
248     @Override
249     public void onMetaChanged() {
250         // do nothing
251     }
252
253     /**
254      * LoaderCallbacks identifier
255      */
256     public abstract int getLoaderId();
257
258     /**
259      * If the user clisk play all
260      *
261      * @param position the position of the item clicked or -1 if shuffle all
262      */
263     public abstract void playAll(int position);
264
265 }