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.profile;
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;
19 import android.support.v4.app.LoaderManager.LoaderCallbacks;
20 import android.support.v4.content.Loader;
21 import android.view.LayoutInflater;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.widget.AbsListView;
25 import android.widget.AdapterView;
26 import android.widget.AdapterView.OnItemClickListener;
27 import android.widget.ListView;
29 import com.cyngn.eleven.MusicStateListener;
30 import com.cyngn.eleven.R;
31 import com.cyngn.eleven.adapters.SongAdapter;
32 import com.cyngn.eleven.model.Song;
33 import com.cyngn.eleven.recycler.RecycleHolder;
34 import com.cyngn.eleven.sectionadapter.SectionAdapter;
35 import com.cyngn.eleven.sectionadapter.SectionListContainer;
36 import com.cyngn.eleven.ui.activities.BaseActivity;
37 import com.cyngn.eleven.utils.PopupMenuHelper;
38 import com.cyngn.eleven.utils.SongPopupMenuHelper;
39 import com.cyngn.eleven.widgets.IPopupMenuCallback;
40 import com.cyngn.eleven.widgets.LoadingEmptyContainer;
41 import com.cyngn.eleven.widgets.NoResultsContainer;
43 import java.util.TreeSet;
46 * This class is used to display all of the songs
48 * @author Andrew Neal (andrewdneal@gmail.com)
50 public abstract class BasicSongFragment extends Fragment implements
51 LoaderCallbacks<SectionListContainer<Song>>, OnItemClickListener, MusicStateListener {
56 protected ViewGroup mRootView;
59 * The adapter for the list
61 protected SectionAdapter<Song, SongAdapter> mAdapter;
66 protected ListView mListView;
71 protected PopupMenuHelper mPopupMenuHelper;
74 * This holds the loading progress bar as well as the no results message
76 protected LoadingEmptyContainer mLoadingEmptyContainer;
79 * Empty constructor as per the {@link Fragment} documentation
81 public BasicSongFragment() {
88 public void onCreate(final Bundle savedInstanceState) {
89 super.onCreate(savedInstanceState);
90 mPopupMenuHelper = new SongPopupMenuHelper(getActivity(), getFragmentManager()) {
92 public Song getSong(int position) {
93 return mAdapter.getTItem(position);
97 protected void updateMenuIds(PopupMenuType type, TreeSet<Integer> set) {
98 super.updateMenuIds(type, set);
99 BasicSongFragment.this.updateMenuIds(set);
103 // Create the adapter
104 mAdapter = createAdapter();
105 mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
107 public void onPopupMenuClicked(View v, int position) {
108 mPopupMenuHelper.showPopupMenu(v, position);
113 protected void updateMenuIds(TreeSet<Integer> set) {
114 // do nothing - let subclasses override
121 public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
122 final Bundle savedInstanceState) {
123 // The View for the fragment's UI
124 mRootView = (ViewGroup) inflater.inflate(R.layout.list_base, null);
125 // set the background on the root view
126 mRootView.setBackgroundColor(getResources().getColor(R.color.background_color));
127 // Initialize the list
128 mListView = (ListView) mRootView.findViewById(R.id.list_base);
129 // Set the data behind the list
130 mListView.setAdapter(mAdapter);
131 // Release any references to the recycled Views
132 mListView.setRecyclerListener(new RecycleHolder());
133 // Play the selected song
134 mListView.setOnItemClickListener(this);
135 // To help make scrolling smooth
136 mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
138 public void onScrollStateChanged(AbsListView view, int scrollState) {
139 // Pause disk cache access to ensure smoother scrolling
140 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING
141 || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
142 mAdapter.getUnderlyingAdapter().setPauseDiskCache(true);
144 mAdapter.getUnderlyingAdapter().setPauseDiskCache(false);
145 mAdapter.notifyDataSetChanged();
150 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
156 mLoadingEmptyContainer = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
157 // Setup the container strings
158 setupNoResultsContainer(mLoadingEmptyContainer.getNoResultsContainer());
159 mListView.setEmptyView(mLoadingEmptyContainer);
161 // Register the music status listener
162 ((BaseActivity)getActivity()).setMusicStateListenerListener(this);
168 public void onDestroyView() {
169 super.onDestroyView();
171 ((BaseActivity)getActivity()).removeMusicStateListenerListener(this);
175 * This allows subclasses to customize the look and feel of the no results container
176 * @param empty NoResultsContainer class
178 public void setupNoResultsContainer(final NoResultsContainer empty) {
186 public void onActivityCreated(final Bundle savedInstanceState) {
187 super.onActivityCreated(savedInstanceState);
189 getFragmentLoaderManager().initLoader(getLoaderId(), null, this);
196 public void onItemClick(final AdapterView<?> parent, final View view, final int position,
205 public void onLoadFinished(final Loader<SectionListContainer<Song>> loader,
206 final SectionListContainer<Song> data) {
207 // Check for any errors
208 if (data.mListResults.isEmpty()) {
209 mLoadingEmptyContainer.showNoResults();
214 mAdapter.setData(data);
218 * Restarts the loader.
220 public void refresh() {
221 // Wait a moment for the preference to change.
222 SystemClock.sleep(10);
230 public void restartLoader() {
231 // Update the list when the user deletes any items
232 getFragmentLoaderManager().restartLoader(getLoaderId(), null, this);
239 public void onLoaderReset(final Loader<SectionListContainer<Song>> loader) {
240 // Clear the data in the adapter
245 * If the subclasses want to use a customized SongAdapter they can override this method
246 * @return the Song adapter
248 protected SectionAdapter<Song, SongAdapter> createAdapter() {
249 return new SectionAdapter(getActivity(),
252 R.layout.list_item_normal
258 * Allow subclasses to specify a different loader manager
259 * @return Loader Manager to use
261 public LoaderManager getFragmentLoaderManager() {
262 return getLoaderManager();
266 public void onMetaChanged() {
271 public void onPlaylistChanged() {
276 * LoaderCallbacks identifier
278 public abstract int getLoaderId();
281 * If the user clisk play all
283 * @param position the position of the item clicked or -1 if shuffle all
285 public abstract void playAll(int position);