Some fragments intentionally don't show the loading dialog on recreate to prevent a split second flash on the screen
Loading is delayed by 300ms for better user experience
Fixed a small bug in the RecentStore
https://cyanogen.atlassian.net/browse/MUSIC-63
Change-Id: I5bd7ee25234d0146887f152bbcb57fed6bbb2c01
android:textColor="@color/default_text_color" />
</RelativeLayout>
+ <include
+ layout="@layout/loading_empty_container" />
+
<ListView
android:id="@+id/songs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_color" >
+ <include
+ layout="@layout/loading_empty_container" />
+
<ListView
android:id="@+id/songs"
android:layout_width="match_parent"
android:paddingTop="@dimen/list_preferred_item_padding">
<include
- layout="@layout/no_results_message" />
+ layout="@layout/loading_empty_container" />
<GridView
android:id="@+id/grid_base"
android:layout_height="match_parent">
<include
- layout="@layout/no_results_message" />
+ layout="@layout/loading_empty_container" />
<com.cyngn.eleven.dragdrop.DragSortListView
android:id="@+id/list_base"
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 Cyanogen, Inc.
+-->
+
+<com.cyngn.eleven.widgets.LoadingEmptyContainer
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/loading_empty_container"
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_centerInParent="true"
+ android:layout_gravity="center">
+
+ <ProgressBar
+ android:id="@+id/progressbar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+
+ <include
+ layout="@layout/no_results_message" />
+</com.cyngn.eleven.widgets.LoadingEmptyContainer>
android:layout_height="match_parent">
<include
- layout="@layout/no_results_message" />
-
- <include
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
layout="@layout/list_base" />
<include
import java.util.List;
-public class AlbumDetailSongAdapter extends DetailSongAdapter {
+public abstract class AlbumDetailSongAdapter extends DetailSongAdapter {
private AlbumDetailFragment mFragment;
public AlbumDetailSongAdapter(Activity activity, AlbumDetailFragment fragment) {
@Override // LoaderCallbacks
public Loader<List<Song>> onCreateLoader(int id, Bundle args) {
+ onLoading();
return new AlbumSongLoader(mActivity, args.getLong(Config.ID));
}
import java.util.List;
-public class ArtistDetailSongAdapter extends DetailSongAdapter {
+public abstract class ArtistDetailSongAdapter extends DetailSongAdapter {
public ArtistDetailSongAdapter(Activity activity) {
super(activity);
@Override // LoaderCallbacks
public Loader<List<Song>> onCreateLoader(int id, Bundle args) {
+ onLoading();
return new ArtistSongLoader(mActivity, args.getLong(Config.ID));
}
import java.util.List;
public abstract class DetailSongAdapter extends BaseAdapter
-implements LoaderCallbacks<List<Song>>, OnItemClickListener, IPopupMenuCallback {
+ implements LoaderCallbacks<List<Song>>, OnItemClickListener, IPopupMenuCallback {
protected final Activity mActivity;
private final ImageFetcher mImageFetcher;
private final LayoutInflater mInflater;
private List<Song> mSongs = Collections.emptyList();
private IListener mListener;
- private IEmptyAdapterCallback mEmptyCallback;
public DetailSongAdapter(final Activity activity) {
mActivity = activity;
}
protected abstract int rowLayoutId();
+ protected abstract void onLoading();
+ protected abstract void onNoResults();
@Override // OnItemClickListener
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
@Override // LoaderCallbacks
public void onLoadFinished(Loader<List<Song>> loader, List<Song> songs) {
if (songs.isEmpty()) {
- if (mEmptyCallback != null) {
- mEmptyCallback.onEmptyAdapter();
- }
-
+ onNoResults();
return;
}
mSongs = songs;
mListener = listener;
}
- public void setOnEmptyAdapterListener(IEmptyAdapterCallback callback) {
- mEmptyCallback = callback;
- }
-
protected abstract Holder newHolder(View root, ImageFetcher fetcher);
protected static abstract class Holder {
+++ /dev/null
-/*
- * Copyright (C) 2014 Cyanogen, Inc.
- */
-package com.cyngn.eleven.adapters;
-
-public interface IEmptyAdapterCallback {
- public void onEmptyAdapter();
-}
// if our db is too large, delete the extra items
Cursor oldest = null;
try {
- database.query(RecentStoreColumns.NAME,
+ oldest = database.query(RecentStoreColumns.NAME,
new String[]{RecentStoreColumns.TIMEPLAYED}, null, null, null, null,
RecentStoreColumns.TIMEPLAYED + " ASC");
* unloads the underlying adapter
*/
public void unload() {
+ mSections.clear();
mUnderlyingAdapter.unload();
notifyDataSetChanged();
}
}
public void clear() {
+ mSections.clear();
mUnderlyingAdapter.clear();
mSections.clear();
}
import com.cyngn.eleven.utils.SectionCreatorUtils;
import com.cyngn.eleven.utils.SectionCreatorUtils.IItemCompare;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import com.cyngn.eleven.widgets.NoResultsContainer;
import java.util.ArrayList;
private InputMethodManager mImm;
/**
- * The view that container the no search results text
+ * The view that container the no search results text and the loading progress bar
*/
- private NoResultsContainer mNoResultsContainer;
+ private LoadingEmptyContainer mLoadingEmptyContainer;
/**
* List view adapter
}
});
+ mLoadingEmptyContainer = (LoadingEmptyContainer) findViewById(R.id.loading_empty_container);
// setup the no results container
- mNoResultsContainer = (NoResultsContainer)findViewById(R.id.no_results_container);
- mNoResultsContainer.setMainText(R.string.empty_search);
- mNoResultsContainer.setSecondaryText(R.string.empty_search_check);
+ NoResultsContainer noResults = mLoadingEmptyContainer.getNoResultsContainer();
+ noResults.setMainText(R.string.empty_search);
+ noResults.setSecondaryText(R.string.empty_search_check);
initListView();
mListView.setOnScrollListener(this);
// sets the touch listener
mListView.setOnTouchListener(this);
- // If we setEmptyView with noResultsContainer it causes a crash in DragSortListView
+ // If we setEmptyView with mLoadingEmptyContainer it causes a crash in DragSortListView
// when updating the search. For now let's manually toggle visibility and come back
// to this later
- //mListView.setEmptyView(mNoResultsContainer);
+ //mListView.setEmptyView(mLoadingEmptyContainer);
// load the search history list view
mSearchHistoryListView = (ListView)findViewById(R.id.list_search_history);
setLoading();
// set the no results string ahead of time in case the user changes the string whiel loading
- mNoResultsContainer.setMainHighlightText("\"" + mFilterString + "\"");
+ NoResultsContainer noResults = mLoadingEmptyContainer.getNoResultsContainer();
+ noResults.setMainHighlightText("\"" + mFilterString + "\"");
// if we are at the top level, create a comparator to separate the different types into
// their own sections (artists, albums, etc)
*/
@Override
public void onLoaderReset(final Loader<SectionListContainer<SearchResult>> loader) {
+ mAdapter.unload();
}
/**
mSearchHistoryListView.setVisibility(View.INVISIBLE);
mListView.setVisibility(View.INVISIBLE);
- mNoResultsContainer.setVisibility(View.INVISIBLE);
+ mLoadingEmptyContainer.setVisibility(View.INVISIBLE);
switch (mCurrentState) {
case SearchHistory:
mListView.setVisibility(View.VISIBLE);
break;
case Empty:
- mNoResultsContainer.setVisibility(View.VISIBLE);
+ mLoadingEmptyContainer.setVisibility(View.VISIBLE);
+ mLoadingEmptyContainer.showNoResults();
break;
- default:
- // Don't show anything for now - we need a loading screen
- // see bug: https://cyanogen.atlassian.net/browse/MUSIC-63
+ case Loading:
+ mLoadingEmptyContainer.setVisibility(View.VISIBLE);
+ mLoadingEmptyContainer.showLoading();
break;
}
}
@Override
public void onLoaderReset(Loader<ArrayAdapter<String>> cursorAdapterLoader) {
-
+ ((ArrayAdapter)mSearchHistoryListView.getAdapter()).clear();
}
}
import com.cyngn.eleven.utils.PopupMenuHelper;
import com.cyngn.eleven.utils.SongPopupMenuHelper;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import com.cyngn.eleven.widgets.PopupMenuButton;
import java.util.List;
private long mAlbumId;
private String mArtistName;
private String mAlbumName;
+ private LoadingEmptyContainer mLoadingEmptyContainer;
@Override
protected int getLayoutToInflate() {
private void setupSongList() {
mSongs = (ListView)mRootView.findViewById(R.id.songs);
- mSongAdapter = new AlbumDetailSongAdapter(getActivity(), this);
+ mSongAdapter = new AlbumDetailSongAdapter(getActivity(), this) {
+ @Override
+ protected void onLoading() {
+ mLoadingEmptyContainer.showLoading();
+ }
+
+ @Override
+ protected void onNoResults() {
+ getContainingActivity().postRemoveFragment(AlbumDetailFragment.this);
+ }
+ };
mSongAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
@Override
public void onPopupMenuClicked(View v, int position) {
});
mSongs.setAdapter(mSongAdapter);
mSongs.setOnItemClickListener(mSongAdapter);
+ mLoadingEmptyContainer =
+ (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
+ mSongs.setEmptyView(mLoadingEmptyContainer);
}
/** called back by song loader */
/** use the first song on the album to get a genre */
if(!songs.isEmpty()) {
- GenreFetcher.fetch(getActivity(), (int)songs.get(0).mSongId, mGenre);
- } else {
- // no songs, remove from stack
- getContainingActivity().postRemoveFragment(this);
+ GenreFetcher.fetch(getActivity(), (int) songs.get(0).mSongId, mGenre);
}
}
import com.cyngn.eleven.utils.NavUtils;
import com.cyngn.eleven.utils.PopupMenuHelper;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import com.cyngn.eleven.widgets.NoResultsContainer;
import com.viewpagerindicator.TitlePageIndicator;
*/
private PopupMenuHelper mPopupMenuHelper;
+ /**
+ * This holds the loading progress bar as well as the no results message
+ */
+ private LoadingEmptyContainer mLoadingEmptyContainer;
+
@Override
public int getLoaderId() {
return PagerAdapter.MusicFragments.ALBUM.ordinal();
*/
@Override
public Loader<SectionListContainer<Album>> onCreateLoader(final int id, final Bundle args) {
+ mLoadingEmptyContainer.showLoading();
// if we ever decide to add section headers for grid items, we can pass a compartor
// instead of null
return new SectionCreator<Album>(getActivity(), new AlbumLoader(getActivity()), null);
final SectionListContainer<Album> data) {
// Check for any errors
if (data.mListResults.isEmpty()) {
- // Set the empty text
- final NoResultsContainer empty = (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
- mGridView.setEmptyView(empty);
+ mLoadingEmptyContainer.showNoResults();
return;
}
public void refresh() {
// Wait a moment for the preference to change.
SystemClock.sleep(10);
- restartLoader(null, this);
+ restartLoader();
}
/**
} else {
mGridView.setNumColumns(TWO);
}
+
+ // Show progress bar
+ mLoadingEmptyContainer = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
+ mGridView.setEmptyView(mLoadingEmptyContainer);
}
}
import com.cyngn.eleven.R;
import com.cyngn.eleven.adapters.ArtistDetailAlbumAdapter;
import com.cyngn.eleven.adapters.ArtistDetailSongAdapter;
-import com.cyngn.eleven.adapters.IEmptyAdapterCallback;
import com.cyngn.eleven.cache.ImageFetcher;
-import com.cyngn.eleven.lastfm.Artist;
import com.cyngn.eleven.menu.FragmentMenuItems;
import com.cyngn.eleven.model.Album;
import com.cyngn.eleven.model.Song;
import com.cyngn.eleven.utils.AlbumPopupMenuHelper;
import com.cyngn.eleven.utils.SongPopupMenuHelper;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import java.util.TreeSet;
private SongPopupMenuHelper mSongPopupMenuHelper;
private AlbumPopupMenuHelper mAlbumPopupMenuHelper;
+ private LoadingEmptyContainer mLoadingEmptyContainer;
+
@Override
protected int getLayoutToInflate() { return R.layout.activity_artist_detail; }
inflate(R.layout.artist_detail_header, mSongs, false);
mSongs.addHeaderView(mHeader);
mSongs.setOnScrollListener(this);
- mSongAdapter = new ArtistDetailSongAdapter(getActivity());
- mSongAdapter.setOnEmptyAdapterListener(new IEmptyAdapterCallback() {
+ mSongAdapter = new ArtistDetailSongAdapter(getActivity()) {
+ @Override
+ protected void onLoading() {
+ mLoadingEmptyContainer.showLoading();
+ }
+
@Override
- public void onEmptyAdapter() {
+ protected void onNoResults() {
// no results - because the user deleted the last item - pop our fragment
// from the stack
getContainingActivity().postRemoveFragment(ArtistDetailFragment.this);
}
- });
+ };
mSongAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
@Override
public void onPopupMenuClicked(View v, int position) {
});
mSongs.setAdapter(mSongAdapter);
mSongs.setOnItemClickListener(mSongAdapter);
+ mLoadingEmptyContainer =
+ (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
+ mSongs.setEmptyView(mLoadingEmptyContainer);
}
private void setupPopupMenuHelpers() {
import com.cyngn.eleven.utils.SectionCreatorUtils;
import com.cyngn.eleven.utils.SectionCreatorUtils.IItemCompare;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import com.cyngn.eleven.widgets.NoResultsContainer;
import com.viewpagerindicator.TitlePageIndicator;
private PopupMenuHelper mPopupMenuHelper;
/**
+ * Loading container and no results container
+ */
+ private LoadingEmptyContainer mLoadingEmptyContainer;
+
+ /**
* Empty constructor as per the {@link Fragment} documentation
*/
public ArtistFragment() {
*/
@Override
public Loader<SectionListContainer<Artist>> onCreateLoader(final int id, final Bundle args) {
+ mLoadingEmptyContainer.showLoading();
final Context context = getActivity();
IItemCompare<Artist> comparator = SectionCreatorUtils.createArtistComparison(context);
return new SectionCreator<Artist>(getActivity(), new ArtistLoader(context), comparator);
final SectionListContainer<Artist> data) {
// Check for any errors
if (data.mListResults.isEmpty()) {
- // Set the empty text
- final NoResultsContainer empty = (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
- mListView.setEmptyView(empty);
+ mLoadingEmptyContainer.showNoResults();
return;
}
public void refresh() {
// Wait a moment for the preference to change.
SystemClock.sleep(10);
- restartLoader(null, this);
+ restartLoader();
}
/**
mListView = (ListView)mRootView.findViewById(R.id.list_base);
// Set the data behind the list
mListView.setAdapter(mAdapter);
+ // set the loading and empty view container
+ mLoadingEmptyContainer = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
+ mListView.setEmptyView(mLoadingEmptyContainer);
// Set up the helpers
initAbsListView(mListView);
}
import com.cyngn.eleven.utils.PopupMenuHelper;
import com.cyngn.eleven.utils.SongPopupMenuHelper;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import com.cyngn.eleven.widgets.NoResultsContainer;
import java.util.ArrayList;
private View mHeaderContainer;
private ImageView mPlaylistImageView;
- private NoResultsContainer mNoResultsContainer;
+ private LoadingEmptyContainer mLoadingEmptyContainer;
private TextView mNumberOfSongs;
private TextView mDurationOfPlaylist;
setupHero();
setupSongList();
- setupNoResultsContainer();
}
@Override
mListView.setVerticalScrollBarEnabled(false);
mListView.setFastScrollEnabled(false);
mListView.setPadding(0, 0, 0, 0);
+
+ // Adjust the progress bar padding to account for the header
+ int padTop = getResources().getDimensionPixelSize(R.dimen.playlist_detail_header_height);
+ mRootView.findViewById(R.id.progressbar).setPadding(0, padTop, 0, 0);
+
+ // set the loading and empty view container
+ mLoadingEmptyContainer =
+ (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
+ setupNoResultsContainer(mLoadingEmptyContainer.getNoResultsContainer());
+ mListView.setEmptyView(mLoadingEmptyContainer);
}
- private void setupNoResultsContainer() {
- mNoResultsContainer = (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
- mNoResultsContainer.setMainText(R.string.empty_playlist_main);
- mNoResultsContainer.setSecondaryText(R.string.empty_playlist_secondary);
+ private void setupNoResultsContainer(final NoResultsContainer container) {
+ container.setMainText(R.string.empty_playlist_main);
+ container.setSecondaryText(R.string.empty_playlist_secondary);
}
/**
@Override
public Loader<List<Song>> onCreateLoader(int i, Bundle bundle) {
+ mLoadingEmptyContainer.showLoading();
+
return new PlaylistSongLoader(getActivity(), mPlaylistId);
}
@Override
public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) {
if (data.isEmpty()) {
- // set the empty view - only do it here so we don't see the empty view by default
- // while the list is loading
- mListView.setEmptyView(mNoResultsContainer);
+ mLoadingEmptyContainer.showNoResults();
// hide the header container
- mHeaderContainer.setVisibility(View.GONE);
+ mHeaderContainer.setVisibility(View.INVISIBLE);
// Return the correct count
mAdapter.setCount(new ArrayList<Song>());
@Override
public void restartLoader() {
+ // unload the adapter - this will also get the loading progress bar to show
+ mAdapter.unload();
+
getLoaderManager().restartLoader(0, getArguments(), this);
}
}
\ No newline at end of file
import com.cyngn.eleven.utils.NavUtils;
import com.cyngn.eleven.utils.PopupMenuHelper;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import java.util.List;
private PopupMenuHelper mPopupMenuHelper;
/**
+ * This holds the loading progress bar as well as the no results message
+ */
+ private LoadingEmptyContainer mLoadingEmptyContainer;
+
+ /**
* Empty constructor as per the {@link Fragment} documentation
*/
public PlaylistFragment() {
mListView.setRecyclerListener(new RecycleHolder());
// Play the selected song
mListView.setOnItemClickListener(this);
+ // Setup the loading and empty state
+ mLoadingEmptyContainer =
+ (LoadingEmptyContainer)rootView.findViewById(R.id.loading_empty_container);
+ mListView.setEmptyView(mLoadingEmptyContainer);
// Register the music status listener
((BaseActivity)getActivity()).setMusicStateListenerListener(this);
*/
@Override
public Loader<List<Playlist>> onCreateLoader(final int id, final Bundle args) {
+ // show the loading progress bar
+ mLoadingEmptyContainer.showLoading();
return new PlaylistLoader(getActivity());
}
public void onLoadFinished(final Loader<List<Playlist>> loader, final List<Playlist> data) {
// Check for any errors
if (data.isEmpty()) {
+ mLoadingEmptyContainer.showNoResults();
return;
}
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ProgressBar;
import com.cyngn.eleven.MusicPlaybackService;
import com.cyngn.eleven.R;
import com.cyngn.eleven.utils.PopupMenuHelper;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
import com.cyngn.eleven.widgets.NoResultsContainer;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import com.cyngn.eleven.widgets.PlayPauseProgressButton;
import java.lang.ref.WeakReference;
*/
private PopupMenuHelper mPopupMenuHelper;
+ /**
+ * Root view
+ */
private ViewGroup mRootView;
/**
+ * This holds the loading progress bar as well as the no results message
+ */
+ private LoadingEmptyContainer mLoadingEmptyContainer;
+
+ /**
* Empty constructor as per the {@link Fragment} documentation
*/
public QueueFragment() {
mListView.setDragScrollProfile(this);
// Enable fast scroll bars
mListView.setFastScrollEnabled(true);
+ // Setup the loading and empty state
+ mLoadingEmptyContainer =
+ (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
+ // Setup the container strings
+ setupNoResultsContainer(mLoadingEmptyContainer.getNoResultsContainer());
+ mListView.setEmptyView(mLoadingEmptyContainer);
return mRootView;
}
i <= mListView.getLastVisiblePosition(); i++) {
View childView = mListView.getChildAt(i);
if (childView != null) {
- PlayPauseProgressButton button = (PlayPauseProgressButton) childView.findViewById(R.id.playPauseProgressButton);
-
+ PlayPauseProgressButton button =
+ (PlayPauseProgressButton) childView.findViewById(R.id.playPauseProgressButton);
// pause or resume based on the flag
if (pause) {
button.pause();
*/
@Override
public Loader<List<Song>> onCreateLoader(final int id, final Bundle args) {
+ mLoadingEmptyContainer.showLoading();
return new QueueLoader(getActivity());
}
mAdapter.unload(); // Start fresh
if (data.isEmpty()) {
- // No songs found, bring up the empty view
- final NoResultsContainer empty =
- (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
- // Setup the container strings
- setupNoResultsContainer(empty);
- // set the empty view into the list view
- mListView.setEmptyView(empty);
+ mLoadingEmptyContainer.showNoResults();
mAdapter.setCurrentlyPlayingSongId(SongAdapter.NOTHING_PLAYING);
((SlidingPanelActivity)getActivity()).clearMetaInfo();
} else {
*/
@Override
public Loader<SectionListContainer<Song>> onCreateLoader(final int id, final Bundle args) {
+ // show the loading progress bar
+ mLoadingEmptyContainer.showLoading();
+
TopTracksLoader loader = new TopTracksLoader(getActivity(),
TopTracksLoader.QueryType.RecentSongs);
return new SectionCreator<Song>(getActivity(), loader, null);
@Override
public void onMetaChanged() {
// refresh the list since a track playing means it should be recently played
- getLoaderManager().restartLoader(LOADER, null, this);
+ restartLoader();
}
@Override
*/
@Override
public Loader<SectionListContainer<Song>> onCreateLoader(final int id, final Bundle args) {
+ // show the loading progress bar
+ mLoadingEmptyContainer.showLoading();
+
// get the context
Context context = getActivity();
import com.cyngn.eleven.utils.PopupMenuHelper;
import com.cyngn.eleven.utils.SongPopupMenuHelper;
import com.cyngn.eleven.widgets.IPopupMenuCallback;
+import com.cyngn.eleven.widgets.LoadingEmptyContainer;
import com.cyngn.eleven.widgets.NoResultsContainer;
import java.util.TreeSet;
/**
* Pop up menu helper
*/
- private PopupMenuHelper mPopupMenuHelper;
+ protected PopupMenuHelper mPopupMenuHelper;
+
+ /**
+ * This holds the loading progress bar as well as the no results message
+ */
+ protected LoadingEmptyContainer mLoadingEmptyContainer;
/**
* Empty constructor as per the {@link Fragment} documentation
}
});
+ // Show progress bar
+ mLoadingEmptyContainer = (LoadingEmptyContainer)mRootView.findViewById(R.id.loading_empty_container);
+ // Setup the container strings
+ setupNoResultsContainer(mLoadingEmptyContainer.getNoResultsContainer());
+ mListView.setEmptyView(mLoadingEmptyContainer);
+
// Register the music status listener
((BaseActivity)getActivity()).setMusicStateListenerListener(this);
final SectionListContainer<Song> data) {
// Check for any errors
if (data.mListResults.isEmpty()) {
- // Set the empty text
- final NoResultsContainer empty =
- (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
- // Setup the container strings
- setupNoResultsContainer(empty);
- // set the empty view into the list view
- mListView.setEmptyView(empty);
+ mLoadingEmptyContainer.showNoResults();
return;
}
public void refresh() {
// Wait a moment for the preference to change.
SystemClock.sleep(10);
- getFragmentLoaderManager().restartLoader(getLoaderId(), null, this);
+ restartLoader();
}
/**
*/
@Override
public Loader<SectionListContainer<Song>> onCreateLoader(final int id, final Bundle args) {
+ // show the loading progress bar
+ mLoadingEmptyContainer.showLoading();
+
LastAddedLoader loader = new LastAddedLoader(getActivity());
return new SectionCreator<Song>(getActivity(), loader, null);
}
*/
@Override
public Loader<SectionListContainer<Song>> onCreateLoader(final int id, final Bundle args) {
+ // show the loading progress bar
+ mLoadingEmptyContainer.showLoading();
+
TopTracksLoader loader = new TopTracksLoader(getActivity(),
TopTracksLoader.QueryType.TopTracks);
return new SectionCreator<Song>(getActivity(), loader, null);
--- /dev/null
+/*
+ * Copyright (C) 2014 Cyanogen, Inc.
+ */
+package com.cyngn.eleven.widgets;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.cyngn.eleven.R;
+
+/**
+ * This class is the default empty state view for most listviews/fragments
+ * It allows the ability to set a main text, a main highlight text and a secondary text
+ * By default this container has some strings loaded, but other classes can call the apis to change
+ * the text
+ */
+public class LoadingEmptyContainer extends FrameLayout {
+ private static final int LOADING_DELAY = 300;
+
+ private Handler mHandler;
+ private Runnable mShowLoadingRunnable;
+
+ public LoadingEmptyContainer(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ mHandler = new Handler();
+ mShowLoadingRunnable = new Runnable() {
+ @Override
+ public void run() {
+ findViewById(R.id.progressbar).setVisibility(View.VISIBLE);
+ getNoResultsContainer().setVisibility(View.INVISIBLE);
+ }
+ };
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ hideAll();
+ }
+
+ public void hideAll() {
+ findViewById(R.id.progressbar).setVisibility(View.INVISIBLE);
+ getNoResultsContainer().setVisibility(View.INVISIBLE);
+ }
+
+ public void showLoading() {
+ hideAll();
+
+ if (!mHandler.hasCallbacks(mShowLoadingRunnable)) {
+ mHandler.postDelayed(mShowLoadingRunnable, LOADING_DELAY);
+ }
+ }
+
+ public void showNoResults() {
+ mHandler.removeCallbacks(mShowLoadingRunnable);
+
+ findViewById(R.id.progressbar).setVisibility(View.INVISIBLE);
+ getNoResultsContainer().setVisibility(View.VISIBLE);
+ }
+
+ public NoResultsContainer getNoResultsContainer() {
+ return (NoResultsContainer)findViewById(R.id.no_results_container);
+ }
+}