Make library categories configurable
This commit is contained in:
parent
ddf00ab488
commit
0e5adaf361
4 changed files with 235 additions and 31 deletions
|
|
@ -10,14 +10,17 @@ import android.util.SparseArray;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.model.Category;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.AlbumsFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.AlbumsFragment;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.ArtistsFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.ArtistsFragment;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.GenresFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.GenresFragment;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.PlaylistsFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.PlaylistsFragment;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.SongsFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.SongsFragment;
|
||||||
|
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
|
@ -30,33 +33,29 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter {
|
||||||
@NonNull
|
@NonNull
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private final String[] titles;
|
|
||||||
|
|
||||||
public MusicLibraryPagerAdapter(@NonNull final Context context, final FragmentManager fragmentManager) {
|
public MusicLibraryPagerAdapter(@NonNull final Context context, final FragmentManager fragmentManager) {
|
||||||
super(fragmentManager);
|
super(fragmentManager);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
titles = new String[]{
|
setCategories(PreferenceUtil.getInstance(context).getLibraryCategories());
|
||||||
context.getResources().getString(R.string.songs),
|
|
||||||
context.getResources().getString(R.string.albums),
|
|
||||||
context.getResources().getString(R.string.artists),
|
|
||||||
context.getResources().getString(R.string.genres),
|
|
||||||
context.getResources().getString(R.string.playlists)
|
|
||||||
};
|
|
||||||
final MusicFragments[] fragments = MusicFragments.values();
|
|
||||||
for (final MusicLibraryPagerAdapter.MusicFragments fragment : fragments) {
|
|
||||||
add(fragment.getFragmentClass(), null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("synthetic-access")
|
public void setCategories(@NonNull ArrayList<Category> categories) {
|
||||||
public void add(@NonNull final Class<? extends Fragment> className, final Bundle params) {
|
mHolderList.clear();
|
||||||
final Holder mHolder = new Holder();
|
|
||||||
mHolder.mClassName = className.getName();
|
|
||||||
mHolder.mParams = params;
|
|
||||||
|
|
||||||
final int mPosition = mHolderList.size();
|
for (int i = 0, size = categories.size(); i < size; i++) {
|
||||||
mHolderList.add(mPosition, mHolder);
|
Category category = categories.get(i);
|
||||||
|
if (category.visible) {
|
||||||
|
MusicFragments fragment = MusicFragments.valueOf(category.id.toString());
|
||||||
|
Holder holder = new Holder();
|
||||||
|
holder.mClassName = fragment.getFragmentClass().getName();
|
||||||
|
holder.title = mContext.getResources()
|
||||||
|
.getString(fragment.getResourceKey())
|
||||||
|
.toUpperCase(Locale.getDefault());
|
||||||
|
mHolderList.add(holder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alignCache();
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,6 +67,23 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter {
|
||||||
return getItem(position);
|
return getItem(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemPosition(@NonNull Object fragment) {
|
||||||
|
for (int i = 0, size = mHolderList.size(); i < size; i++) {
|
||||||
|
Holder holder = mHolderList.get(i);
|
||||||
|
if (holder.mClassName.equals(fragment.getClass().getName())) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return POSITION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
// as fragment position is not fixed, we can't use position as id
|
||||||
|
return MusicFragments.of(getFragment(position).getClass()).ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Object instantiateItem(@NonNull final ViewGroup container, final int position) {
|
public Object instantiateItem(@NonNull final ViewGroup container, final int position) {
|
||||||
|
|
@ -104,30 +120,75 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getPageTitle(final int position) {
|
public CharSequence getPageTitle(final int position) {
|
||||||
return titles[position]
|
return mHolderList.get(position).title;
|
||||||
.toUpperCase(Locale.getDefault());
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aligns the fragment cache with the current category layout.
|
||||||
|
*/
|
||||||
|
private void alignCache() {
|
||||||
|
if (mFragmentArray.size() == 0) return;
|
||||||
|
|
||||||
|
HashMap<String, WeakReference<Fragment>> mappings = new HashMap<>(mFragmentArray.size());
|
||||||
|
|
||||||
|
for (int i = 0, size = mFragmentArray.size(); i < size; i++) {
|
||||||
|
WeakReference<Fragment> ref = mFragmentArray.valueAt(i);
|
||||||
|
Fragment fragment = ref.get();
|
||||||
|
if (fragment != null) {
|
||||||
|
mappings.put(fragment.getClass().getName(), ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0, size = mHolderList.size(); i < size; i++) {
|
||||||
|
WeakReference<Fragment> ref = mappings.get(mHolderList.get(i).mClassName);
|
||||||
|
if (ref != null) {
|
||||||
|
mFragmentArray.put(i, ref);
|
||||||
|
} else {
|
||||||
|
mFragmentArray.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MusicFragments {
|
public enum MusicFragments {
|
||||||
SONG(SongsFragment.class),
|
SONGS(SongsFragment.class, R.string.songs),
|
||||||
ALBUM(AlbumsFragment.class),
|
ALBUMS(AlbumsFragment.class, R.string.albums),
|
||||||
ARTIST(ArtistsFragment.class),
|
ARTISTS(ArtistsFragment.class, R.string.artists),
|
||||||
GENRES(GenresFragment.class),
|
GENRES(GenresFragment.class, R.string.genres),
|
||||||
PLAYLIST(PlaylistsFragment.class);
|
PLAYLISTS(PlaylistsFragment.class, R.string.playlists);
|
||||||
|
|
||||||
private final Class<? extends Fragment> mFragmentClass;
|
private final Class<? extends Fragment> mFragmentClass;
|
||||||
|
private final int key;
|
||||||
|
|
||||||
MusicFragments(final Class<? extends Fragment> fragmentClass) {
|
MusicFragments(final Class<? extends Fragment> fragmentClass, int key) {
|
||||||
mFragmentClass = fragmentClass;
|
mFragmentClass = fragmentClass;
|
||||||
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<? extends Fragment> getFragmentClass() {
|
public Class<? extends Fragment> getFragmentClass() {
|
||||||
return mFragmentClass;
|
return mFragmentClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getResourceKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MusicFragments of(Class<?> cl) {
|
||||||
|
MusicFragments[] fragments = All.FRAGMENTS;
|
||||||
|
for (int i = 0; i < fragments.length; i++) {
|
||||||
|
if (cl.equals(fragments[i].mFragmentClass))
|
||||||
|
return fragments[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Unknown music fragment " + cl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class All {
|
||||||
|
public static final MusicFragments[] FRAGMENTS = values();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static class Holder {
|
private final static class Holder {
|
||||||
String mClassName;
|
String mClassName;
|
||||||
Bundle mParams;
|
Bundle mParams;
|
||||||
|
String title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
package com.kabouzeid.gramophone.model;
|
||||||
|
|
||||||
|
import com.kabouzeid.gramophone.R;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
public class Category {
|
||||||
|
@SerializedName("id")
|
||||||
|
public Id id;
|
||||||
|
|
||||||
|
@SerializedName("index")
|
||||||
|
public int index;
|
||||||
|
|
||||||
|
@SerializedName("checkBox")
|
||||||
|
public boolean visible;
|
||||||
|
|
||||||
|
public Category(Category category) {
|
||||||
|
this.id = category.id;
|
||||||
|
this.visible = category.visible;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category(Id id, boolean visible, int index) {
|
||||||
|
this.id = id;
|
||||||
|
this.visible = visible;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
Category category = (Category) o;
|
||||||
|
|
||||||
|
return id == category.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 0;
|
||||||
|
result = 31 * result + id.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "{id:"+id + ", pos:"+ index + ", vis=" + visible + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Id
|
||||||
|
{
|
||||||
|
SONGS(R.string.songs),
|
||||||
|
ALBUMS(R.string.albums),
|
||||||
|
ARTISTS(R.string.artists),
|
||||||
|
GENRES(R.string.genres),
|
||||||
|
PLAYLISTS(R.string.playlists);
|
||||||
|
|
||||||
|
public final int key;
|
||||||
|
|
||||||
|
private Id(int key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package com.kabouzeid.gramophone.ui.fragments.mainactivity.library;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
@ -34,6 +35,7 @@ import com.kabouzeid.gramophone.ui.activities.MainActivity;
|
||||||
import com.kabouzeid.gramophone.ui.activities.SearchActivity;
|
import com.kabouzeid.gramophone.ui.activities.SearchActivity;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.AbsMainActivityFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.AbsMainActivityFragment;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||||
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager.PlaylistsFragment;
|
||||||
import com.kabouzeid.gramophone.util.PhonographColorUtil;
|
import com.kabouzeid.gramophone.util.PhonographColorUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
|
|
@ -42,7 +44,7 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.Unbinder;
|
import butterknife.Unbinder;
|
||||||
|
|
||||||
public class LibraryFragment extends AbsMainActivityFragment implements CabHolder, MainActivity.MainActivityFragmentCallbacks, ViewPager.OnPageChangeListener {
|
public class LibraryFragment extends AbsMainActivityFragment implements CabHolder, MainActivity.MainActivityFragmentCallbacks, ViewPager.OnPageChangeListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
public static final String TAG = LibraryFragment.class.getSimpleName();
|
public static final String TAG = LibraryFragment.class.getSimpleName();
|
||||||
|
|
||||||
private Unbinder unbinder;
|
private Unbinder unbinder;
|
||||||
|
|
@ -75,6 +77,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
|
PreferenceUtil.getInstance(getActivity()).unregisterOnSharedPreferenceChangedListener(this);
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
pager.removeOnPageChangeListener(this);
|
pager.removeOnPageChangeListener(this);
|
||||||
unbinder.unbind();
|
unbinder.unbind();
|
||||||
|
|
@ -82,6 +85,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
PreferenceUtil.getInstance(getActivity()).registerOnSharedPreferenceChangedListener(this);
|
||||||
setStatusbarColorAuto(view);
|
setStatusbarColorAuto(view);
|
||||||
getMainActivity().setNavigationbarColorAuto();
|
getMainActivity().setNavigationbarColorAuto();
|
||||||
getMainActivity().setTaskDescriptionColorAuto();
|
getMainActivity().setTaskDescriptionColorAuto();
|
||||||
|
|
@ -90,6 +94,20 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
||||||
setUpViewPager();
|
setUpViewPager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||||
|
if (PreferenceUtil.LIBRARY_CATEGORIES.equals(key)) {
|
||||||
|
Fragment current = getCurrentFragment();
|
||||||
|
pagerAdapter.setCategories(PreferenceUtil.getInstance(getActivity()).getLibraryCategories());
|
||||||
|
pager.setOffscreenPageLimit(pagerAdapter.getCount() - 1);
|
||||||
|
int position = pagerAdapter.getItemPosition(current);
|
||||||
|
pager.setCurrentItem(position > -1 ? position : 0);
|
||||||
|
|
||||||
|
// hide the tab bar with single tab
|
||||||
|
tabs.setVisibility(pagerAdapter.getCount() == 1 ? View.GONE : View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setUpToolbar() {
|
private void setUpToolbar() {
|
||||||
int primaryColor = ThemeStore.primaryColor(getActivity());
|
int primaryColor = ThemeStore.primaryColor(getActivity());
|
||||||
appbar.setBackgroundColor(primaryColor);
|
appbar.setBackgroundColor(primaryColor);
|
||||||
|
|
@ -125,7 +143,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPlaylistPage() {
|
private boolean isPlaylistPage() {
|
||||||
return pager.getCurrentItem() == MusicLibraryPagerAdapter.MusicFragments.PLAYLIST.ordinal();
|
return getCurrentFragment() instanceof PlaylistsFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,17 @@ import android.support.annotation.StyleRes;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.helper.SortOrder;
|
import com.kabouzeid.gramophone.helper.SortOrder;
|
||||||
|
import com.kabouzeid.gramophone.model.Category;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.mainactivity.folders.FoldersFragment;
|
import com.kabouzeid.gramophone.ui.fragments.mainactivity.folders.FoldersFragment;
|
||||||
import com.kabouzeid.gramophone.ui.fragments.player.NowPlayingScreen;
|
import com.kabouzeid.gramophone.ui.fragments.player.NowPlayingScreen;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
public final class PreferenceUtil {
|
public final class PreferenceUtil {
|
||||||
public static final String GENERAL_THEME = "general_theme";
|
public static final String GENERAL_THEME = "general_theme";
|
||||||
|
|
@ -74,6 +81,8 @@ public final class PreferenceUtil {
|
||||||
|
|
||||||
public static final String INITIALIZED_BLACKLIST = "initialized_blacklist";
|
public static final String INITIALIZED_BLACKLIST = "initialized_blacklist";
|
||||||
|
|
||||||
|
public static final String LIBRARY_CATEGORIES = "library_categories";
|
||||||
|
|
||||||
private static PreferenceUtil sInstance;
|
private static PreferenceUtil sInstance;
|
||||||
|
|
||||||
private final SharedPreferences mPreferences;
|
private final SharedPreferences mPreferences;
|
||||||
|
|
@ -426,4 +435,55 @@ public final class PreferenceUtil {
|
||||||
public final boolean initializedBlacklist() {
|
public final boolean initializedBlacklist() {
|
||||||
return mPreferences.getBoolean(INITIALIZED_BLACKLIST, false);
|
return mPreferences.getBoolean(INITIALIZED_BLACKLIST, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLibraryCategories(ArrayList<Category> categories) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
|
Set<String> data = new HashSet<>(categories.size());
|
||||||
|
|
||||||
|
for (int i = 0, size = categories.size(); i < size; i++) {
|
||||||
|
Category category = categories.get(i);
|
||||||
|
category.index = i;
|
||||||
|
data.add(gson.toJson(category));
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPreferences.Editor editor = mPreferences.edit();
|
||||||
|
editor.putStringSet(LIBRARY_CATEGORIES, data);
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Category> getLibraryCategories() {
|
||||||
|
Set<String> data = mPreferences.getStringSet(LIBRARY_CATEGORIES, null);
|
||||||
|
if (data != null) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ArrayList<Category> result = new ArrayList<>(Collections.nCopies(data.size(), (Category) null));
|
||||||
|
|
||||||
|
for (String json : data) {
|
||||||
|
Category category = gson.fromJson(json, Category.class);
|
||||||
|
result.set(category.index, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LibraryCategories.DEFAULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Category> getDefaultLibraryCategories() {
|
||||||
|
return LibraryCategories.DEFAULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LibraryCategories {
|
||||||
|
public final static ArrayList<Category> DEFAULTS = getDefaults();
|
||||||
|
|
||||||
|
private static ArrayList<Category> getDefaults() {
|
||||||
|
ArrayList<Category> result = new ArrayList<>();
|
||||||
|
result.add(new Category(Category.Id.SONGS, true, 0));
|
||||||
|
result.add(new Category(Category.Id.ALBUMS, true, 1));
|
||||||
|
result.add(new Category(Category.Id.ARTISTS, true, 2));
|
||||||
|
result.add(new Category(Category.Id.GENRES, true, 3));
|
||||||
|
result.add(new Category(Category.Id.PLAYLISTS, true, 4));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue