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.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;
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;
41 import java.util.TreeSet;
44 * This class is used to display all of the songs
46 * @author Andrew Neal (andrewdneal@gmail.com)
48 public abstract class BasicSongFragment extends Fragment implements
49 LoaderCallbacks<SectionListContainer<Song>>, OnItemClickListener, MusicStateListener {
54 protected ViewGroup mRootView;
57 * The adapter for the list
59 protected SectionAdapter<Song, SongAdapter> mAdapter;
64 protected ListView mListView;
69 private PopupMenuHelper mPopupMenuHelper;
72 * Empty constructor as per the {@link Fragment} documentation
74 public BasicSongFragment() {
81 public void onAttach(final Activity activity) {
82 super.onAttach(activity);
83 // Register the music status listener
84 ((BaseActivity)activity).setMusicStateListenerListener(this);
91 public void onCreate(final Bundle savedInstanceState) {
92 super.onCreate(savedInstanceState);
93 mPopupMenuHelper = new SongPopupMenuHelper(getActivity(), getFragmentManager()) {
95 public Song getSong(int position) {
96 return mAdapter.getTItem(position);
100 protected void updateMenuIds(PopupMenuType type, TreeSet<Integer> set) {
101 super.updateMenuIds(type, set);
102 BasicSongFragment.this.updateMenuIds(set);
106 // Create the adapter
107 mAdapter = createAdapter();
108 mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
110 public void onPopupMenuClicked(View v, int position) {
111 mPopupMenuHelper.showPopupMenu(v, position);
116 protected void updateMenuIds(TreeSet<Integer> set) {
117 // do nothing - let subclasses 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() {
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);
145 mAdapter.getUnderlyingAdapter().setPauseDiskCache(false);
146 mAdapter.notifyDataSetChanged();
151 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
160 * This allows subclasses to customize the look and feel of the no results container
161 * @param empty NoResultsContainer class
163 public void setupNoResultsContainer(final NoResultsContainer empty) {
171 public void onActivityCreated(final Bundle savedInstanceState) {
172 super.onActivityCreated(savedInstanceState);
174 getLoaderManager().initLoader(getLoaderId(), null, this);
181 public void onItemClick(final AdapterView<?> parent, final View view, final int position,
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);
205 mAdapter.setData(data);
209 * Restarts the loader.
211 public void refresh() {
212 // Wait a moment for the preference to change.
213 SystemClock.sleep(10);
214 getLoaderManager().restartLoader(getLoaderId(), null, this);
221 public void restartLoader() {
222 // Update the list when the user deletes any items
223 getLoaderManager().restartLoader(getLoaderId(), null, this);
230 public void onLoaderReset(final Loader<SectionListContainer<Song>> loader) {
231 // Clear the data in the adapter
236 * If the subclasses want to use a customized SongAdapter they can override this method
237 * @return the Song adapter
239 protected SectionAdapter<Song, SongAdapter> createAdapter() {
240 return new SectionAdapter(getActivity(),
243 R.layout.list_item_normal
249 public void onMetaChanged() {
254 * LoaderCallbacks identifier
256 public abstract int getLoaderId();
259 * If the user clisk play all
261 * @param position the position of the item clicked or -1 if shuffle all
263 public abstract void playAll(int position);