From 0e5adaf361b802aecdda32c7c262afbf70ad7e61 Mon Sep 17 00:00:00 2001 From: Marco Hunsicker <31240866+doompadee@users.noreply.github.com> Date: Sat, 23 Dec 2017 17:10:51 +0100 Subject: [PATCH 01/11] Make library categories configurable --- .../adapter/MusicLibraryPagerAdapter.java | 119 +++++++++++++----- .../kabouzeid/gramophone/model/Category.java | 65 ++++++++++ .../mainactivity/library/LibraryFragment.java | 22 +++- .../gramophone/util/PreferenceUtil.java | 60 +++++++++ 4 files changed, 235 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/com/kabouzeid/gramophone/model/Category.java diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java index ee292b4f..39763fda 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java @@ -10,14 +10,17 @@ import android.util.SparseArray; import android.view.ViewGroup; 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.ArtistsFragment; 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.SongsFragment; +import com.kabouzeid.gramophone.util.PreferenceUtil; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -30,33 +33,29 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter { @NonNull private final Context mContext; - @NonNull - private final String[] titles; - public MusicLibraryPagerAdapter(@NonNull final Context context, final FragmentManager fragmentManager) { super(fragmentManager); mContext = context; - titles = new String[]{ - 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); - } + setCategories(PreferenceUtil.getInstance(context).getLibraryCategories()); } - @SuppressWarnings("synthetic-access") - public void add(@NonNull final Class className, final Bundle params) { - final Holder mHolder = new Holder(); - mHolder.mClassName = className.getName(); - mHolder.mParams = params; + public void setCategories(@NonNull ArrayList categories) { + mHolderList.clear(); - final int mPosition = mHolderList.size(); - mHolderList.add(mPosition, mHolder); + for (int i = 0, size = categories.size(); i < size; i++) { + 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(); } @@ -68,6 +67,23 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter { 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 @Override public Object instantiateItem(@NonNull final ViewGroup container, final int position) { @@ -104,30 +120,75 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter { @NonNull @Override public CharSequence getPageTitle(final int position) { - return titles[position] - .toUpperCase(Locale.getDefault()); + return mHolderList.get(position).title; + } + + /** + * Aligns the fragment cache with the current category layout. + */ + private void alignCache() { + if (mFragmentArray.size() == 0) return; + + HashMap> mappings = new HashMap<>(mFragmentArray.size()); + + for (int i = 0, size = mFragmentArray.size(); i < size; i++) { + WeakReference 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 ref = mappings.get(mHolderList.get(i).mClassName); + if (ref != null) { + mFragmentArray.put(i, ref); + } else { + mFragmentArray.remove(i); + } + } } public enum MusicFragments { - SONG(SongsFragment.class), - ALBUM(AlbumsFragment.class), - ARTIST(ArtistsFragment.class), - GENRES(GenresFragment.class), - PLAYLIST(PlaylistsFragment.class); + SONGS(SongsFragment.class, R.string.songs), + ALBUMS(AlbumsFragment.class, R.string.albums), + ARTISTS(ArtistsFragment.class, R.string.artists), + GENRES(GenresFragment.class, R.string.genres), + PLAYLISTS(PlaylistsFragment.class, R.string.playlists); private final Class mFragmentClass; + private final int key; - MusicFragments(final Class fragmentClass) { + MusicFragments(final Class fragmentClass, int key) { mFragmentClass = fragmentClass; + this.key = key; } public Class getFragmentClass() { 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 { String mClassName; Bundle mParams; + String title; } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/Category.java b/app/src/main/java/com/kabouzeid/gramophone/model/Category.java new file mode 100644 index 00000000..87013376 --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/model/Category.java @@ -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; + } + } +} diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java index dddfd8e8..536102ee 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java @@ -3,6 +3,7 @@ package com.kabouzeid.gramophone.ui.fragments.mainactivity.library; import android.app.Activity; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; import android.support.annotation.NonNull; 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.fragments.mainactivity.AbsMainActivityFragment; 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.PreferenceUtil; import com.kabouzeid.gramophone.util.Util; @@ -42,7 +44,7 @@ import butterknife.BindView; import butterknife.ButterKnife; 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(); private Unbinder unbinder; @@ -75,6 +77,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde @Override public void onDestroyView() { + PreferenceUtil.getInstance(getActivity()).unregisterOnSharedPreferenceChangedListener(this); super.onDestroyView(); pager.removeOnPageChangeListener(this); unbinder.unbind(); @@ -82,6 +85,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + PreferenceUtil.getInstance(getActivity()).registerOnSharedPreferenceChangedListener(this); setStatusbarColorAuto(view); getMainActivity().setNavigationbarColorAuto(); getMainActivity().setTaskDescriptionColorAuto(); @@ -90,6 +94,20 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde 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() { int primaryColor = ThemeStore.primaryColor(getActivity()); appbar.setBackgroundColor(primaryColor); @@ -125,7 +143,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde } private boolean isPlaylistPage() { - return pager.getCurrentItem() == MusicLibraryPagerAdapter.MusicFragments.PLAYLIST.ordinal(); + return getCurrentFragment() instanceof PlaylistsFragment; } @NonNull diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java index 497f371a..18af25a2 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java @@ -9,10 +9,17 @@ import android.support.annotation.StyleRes; import com.kabouzeid.gramophone.R; 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.player.NowPlayingScreen; 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 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 LIBRARY_CATEGORIES = "library_categories"; + private static PreferenceUtil sInstance; private final SharedPreferences mPreferences; @@ -426,4 +435,55 @@ public final class PreferenceUtil { public final boolean initializedBlacklist() { return mPreferences.getBoolean(INITIALIZED_BLACKLIST, false); } + + public void setLibraryCategories(ArrayList categories) { + Gson gson = new Gson(); + + Set 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 getLibraryCategories() { + Set data = mPreferences.getStringSet(LIBRARY_CATEGORIES, null); + if (data != null) { + Gson gson = new Gson(); + ArrayList 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 getDefaultLibraryCategories() { + return LibraryCategories.DEFAULTS; + } + + private static class LibraryCategories { + public final static ArrayList DEFAULTS = getDefaults(); + + private static ArrayList getDefaults() { + ArrayList 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; + } + } } From 70e6c760646f06c4718de8542027e8275bc8f913 Mon Sep 17 00:00:00 2001 From: Marco Hunsicker <31240866+doompadee@users.noreply.github.com> Date: Sat, 23 Dec 2017 17:12:08 +0100 Subject: [PATCH 02/11] Add preferences ui for the library categories setting --- .../gramophone/adapter/CategoryAdapter.java | 205 ++++++++++++++++++ .../preferences/LibraryPreference.java | 24 ++ .../preferences/LibraryPreferenceDialog.java | 108 +++++++++ .../ui/activities/SettingsActivity.java | 4 + .../gramophone/util/SwipeAndDragHelper.java | 56 +++++ .../preference_dialog_library_categories.xml | 11 + ...nce_dialog_library_categories_listitem.xml | 45 ++++ app/src/main/res/values-de/strings.xml | 5 + app/src/main/res/values/strings.xml | 5 + app/src/main/res/xml/pref_general.xml | 5 + 10 files changed, 468 insertions(+) create mode 100644 app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java create mode 100644 app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreference.java create mode 100644 app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java create mode 100644 app/src/main/java/com/kabouzeid/gramophone/util/SwipeAndDragHelper.java create mode 100644 app/src/main/res/layout/preference_dialog_library_categories.xml create mode 100644 app/src/main/res/layout/preference_dialog_library_categories_listitem.xml diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java new file mode 100644 index 00000000..7c0cb9cb --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java @@ -0,0 +1,205 @@ +package com.kabouzeid.gramophone.adapter; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.os.Build; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.content.ContextCompat; +import android.support.v4.graphics.drawable.DrawableCompat; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import com.kabouzeid.appthemehelper.ThemeStore; +import com.kabouzeid.gramophone.R; +import com.kabouzeid.gramophone.util.SwipeAndDragHelper; +import com.kabouzeid.gramophone.model.Category; + +import java.util.ArrayList; + +public class CategoryAdapter extends RecyclerView.Adapter implements SwipeAndDragHelper.ActionCompletionContract { + private ArrayList categories; + private ItemTouchHelper touchHelper; + private ColorStateList color; + + public CategoryAdapter(ArrayList categories, ColorStateList color) { + this.categories = copy(categories); + this.color = color; + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.preference_dialog_library_categories_listitem, parent, false); + return new CategoryViewHolder(view); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + Category category = categories.get(position); + CategoryViewHolder h = (CategoryViewHolder) holder; + h.checkBox.setChecked(category.visible); + h.title.setText(h.title.getResources().getString(category.id.key)); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + h.checkBox.setButtonTintList(color); + } else { + Drawable checkDrawable = + ContextCompat.getDrawable(h.checkBox.getContext(), R.drawable.abc_btn_check_material); + Drawable drawable = DrawableCompat.wrap(checkDrawable); + DrawableCompat.setTintList(drawable, color); + h.checkBox.setButtonDrawable(drawable); + } + + h.checkBox.setOnClickListener((view) -> { + h.checkBox.setChecked(category.visible = !category.visible); + notifyDataSetChanged(); + } + ); + + h.title.setOnClickListener((view) -> { + h.checkBox.setChecked(category.visible = !category.visible); + notifyDataSetChanged(); + } + ); + + h.dragHandle.setOnTouchListener((view, event) -> { + if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + touchHelper.startDrag(h); + } + return false; + } + ); + + Context context = h.dragHandle.getContext(); + int backgroundColor = ThemeStore.textColorSecondary(context); + int borderColor = ThemeStore.textColorSecondaryInverse(context); + int height = getPixel(1, h.dragHandle); + + GradientDrawable d = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.RED, Color.RED}); + d.setStroke(height, backgroundColor); + d.setSize(height * 4, getPixel(16, h.dragHandle)); + + h.dragHandle.setBackground(new DragHandle(h.dragHandle.getResources().getDisplayMetrics().density, backgroundColor, borderColor)); + } + + private static class DragHandle extends Drawable { + private float density; + private Paint shape; + private Paint outline; + + public DragHandle(float density, int color, int borderColor) { + this.shape = new Paint(); + this.shape.setStyle(Paint.Style.FILL); + this.shape.setColor(color); + + this.outline = new Paint(); + this.outline.setAntiAlias(true); + this.outline.setStyle(Paint.Style.STROKE); + this.outline.setColor(borderColor); + + this.density = density; + } + + @Override + public void draw(@NonNull Canvas canvas) { + Rect bounds = getBounds(); + int left = bounds.left + 1; + int top = bounds.top + 1; + int width = bounds.width() - 1; + canvas.save(); + canvas.translate(1, 1); + canvas.drawRect(left, top, width, top + 2 * density, shape); + canvas.drawRect(left, top, width, top + 2 * density, outline); + canvas.translate(0, (density * 2) * 2); + canvas.drawRect(left, top, width, top + 2 * density, shape); + canvas.drawRect(left, top, width, top + 2 * density, outline); + canvas.restore(); + } + + @Override + public void setAlpha(int i) { + } + + @Override + public void setColorFilter(@Nullable ColorFilter filter) { + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + } + + + @Override + public int getItemCount() { + return categories.size(); + } + + @Override + public int getItemViewType(int position) { + return 1; + } + + public void setCategories(ArrayList categories) { + this.categories = copy(categories); + notifyDataSetChanged(); + } + + @Override + public void onViewMoved(int oldPosition, int newPosition) { + Category category = categories.get(oldPosition); + categories.remove(oldPosition); + categories.add(newPosition, category); + notifyItemMoved(oldPosition, newPosition); + } + + public void setTouchHelper(ItemTouchHelper touchHelper) { + this.touchHelper = touchHelper; + } + + public ArrayList getCategories() { + return categories; + } + + + private ArrayList copy(ArrayList categories) { + ArrayList result = new ArrayList<>(); + for (Category category : categories) { + result.add(new Category(category)); + } + return result; + } + + private int getPixel(float dp, View dragHandle) { + return Math.round(dp * dragHandle.getResources().getDisplayMetrics().density); + } + + private static class CategoryViewHolder extends RecyclerView.ViewHolder { + public CheckBox checkBox; + public TextView title; + public View dragHandle; + + public CategoryViewHolder(View view) { + super(view); + checkBox = view.findViewById(R.id.checkbox); + title = view.findViewById(R.id.title); + dragHandle = view.findViewById(R.id.drag_handle); + } + } +} + diff --git a/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreference.java b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreference.java new file mode 100644 index 00000000..7993d30d --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreference.java @@ -0,0 +1,24 @@ +package com.kabouzeid.gramophone.preferences; + +import android.content.Context; +import android.util.AttributeSet; + +import com.kabouzeid.appthemehelper.common.prefs.supportv7.ATEDialogPreference; + +public class LibraryPreference extends ATEDialogPreference { + public LibraryPreference(Context context) { + super(context); + } + + public LibraryPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public LibraryPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public LibraryPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } +} diff --git a/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java new file mode 100644 index 00000000..54774614 --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java @@ -0,0 +1,108 @@ +package com.kabouzeid.gramophone.preferences; + +import android.app.Dialog; +import android.content.res.ColorStateList; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.view.LayoutInflater; +import android.view.View; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.afollestad.materialdialogs.util.DialogUtils; +import com.kabouzeid.appthemehelper.ThemeStore; +import com.kabouzeid.gramophone.R; +import com.kabouzeid.gramophone.adapter.CategoryAdapter; +import com.kabouzeid.gramophone.model.Category; +import com.kabouzeid.gramophone.util.PreferenceUtil; +import com.kabouzeid.gramophone.util.SwipeAndDragHelper; + +import java.util.ArrayList; + + +public class LibraryPreferenceDialog extends DialogFragment { + public static LibraryPreferenceDialog newInstance() { + return new LibraryPreferenceDialog(); + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + LayoutInflater inflater = getActivity().getLayoutInflater(); + View view = inflater.inflate(R.layout.preference_dialog_library_categories, null); + + final ArrayList categories = PreferenceUtil.getInstance(getContext()).getLibraryCategories(); + RecyclerView categoriesView = view.findViewById(R.id.recycler_view); + categoriesView.setLayoutManager(new LinearLayoutManager(getActivity())); + final CategoryAdapter adapter = new CategoryAdapter(categories, getCheckboxColors()); + SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(adapter); + ItemTouchHelper touchHelper = new ItemTouchHelper(swipeAndDragHelper); + adapter.setTouchHelper(touchHelper); + categoriesView.setAdapter(adapter); + touchHelper.attachToRecyclerView(categoriesView); + + MaterialDialog dialog = new MaterialDialog.Builder(getContext()) + .title(R.string.library_categories) + .customView(view, false) + .positiveText(android.R.string.ok) + .negativeText(android.R.string.cancel) + .neutralText(R.string.reset_action) + .autoDismiss(false) + .onNeutral((dialog1, action) -> { + adapter.setCategories(PreferenceUtil.getInstance(getContext()).getDefaultLibraryCategories()); + }) + .onNegative((dialog12, action) -> dismiss()) + .onPositive((dialog13, action) -> { + if (!updateCategories(adapter.getCategories())) { + new MaterialDialog.Builder(getContext()) + .title(R.string.edit_categories) + .content(R.string.at_least_one_category_must_be_enabled) + .positiveText(android.R.string.ok) + .show(); + } else { + dismiss(); + } + }) + .build(); + + return dialog; + } + + private boolean updateCategories(ArrayList categories) { + if (getSelected(categories) == 0) return false; + + PreferenceUtil.getInstance(getContext()).setLibraryCategories(categories); + + return true; + } + + private int getSelected(ArrayList categories) { + int selected = 0; + for (Category category : categories) { + if (category.visible) + selected ++; + } + return selected; + } + + private ColorStateList getCheckboxColors() { + int disabledColor = DialogUtils.getDisabledColor(getContext()); + return new ColorStateList( + new int[][] { + new int[] {android.R.attr.state_enabled, -android.R.attr.state_checked}, + new int[] {android.R.attr.state_enabled, android.R.attr.state_checked}, + new int[] {-android.R.attr.state_enabled, -android.R.attr.state_checked}, + new int[] {-android.R.attr.state_enabled, android.R.attr.state_checked} + }, + new int[] { + DialogUtils.resolveColor(getContext(), R.attr.colorControlNormal), + ThemeStore.accentColor(getContext()), + disabledColor, + disabledColor + }); + } +} diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java index f593c912..8e2d9e6e 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/SettingsActivity.java @@ -31,6 +31,8 @@ import com.kabouzeid.gramophone.appshortcuts.DynamicShortcutManager; import com.kabouzeid.gramophone.misc.NonProAllowedColors; import com.kabouzeid.gramophone.preferences.BlacklistPreference; import com.kabouzeid.gramophone.preferences.BlacklistPreferenceDialog; +import com.kabouzeid.gramophone.preferences.LibraryPreference; +import com.kabouzeid.gramophone.preferences.LibraryPreferenceDialog; import com.kabouzeid.gramophone.preferences.NowPlayingScreenPreference; import com.kabouzeid.gramophone.preferences.NowPlayingScreenPreferenceDialog; import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity; @@ -167,6 +169,8 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia return NowPlayingScreenPreferenceDialog.newInstance(); } else if (preference instanceof BlacklistPreference) { return BlacklistPreferenceDialog.newInstance(); + } else if (preference instanceof LibraryPreference) { + return LibraryPreferenceDialog.newInstance(); } return super.onCreatePreferenceDialog(preference); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/SwipeAndDragHelper.java b/app/src/main/java/com/kabouzeid/gramophone/util/SwipeAndDragHelper.java new file mode 100644 index 00000000..3e28263d --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/util/SwipeAndDragHelper.java @@ -0,0 +1,56 @@ +package com.kabouzeid.gramophone.util; + +import android.graphics.Canvas; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; + +public class SwipeAndDragHelper extends ItemTouchHelper.Callback { + + private ActionCompletionContract contract; + + public SwipeAndDragHelper(ActionCompletionContract contract) { + this.contract = contract; + } + + @Override + public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; + return makeMovementFlags(dragFlags, 0); + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { + contract.onViewMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition()); + return true; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + } + + @Override + public boolean isLongPressDragEnabled() { + return false; + } + + @Override + public void onChildDraw(Canvas c, + RecyclerView recyclerView, + RecyclerView.ViewHolder viewHolder, + float dX, + float dY, + int actionState, + boolean isCurrentlyActive) { + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { + float alpha = 1 - (Math.abs(dX) / recyclerView.getWidth()); + viewHolder.itemView.setAlpha(alpha); + } + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } + + public interface ActionCompletionContract { + void onViewMoved(int oldPosition, int newPosition); + } + +} + diff --git a/app/src/main/res/layout/preference_dialog_library_categories.xml b/app/src/main/res/layout/preference_dialog_library_categories.xml new file mode 100644 index 00000000..4782ec71 --- /dev/null +++ b/app/src/main/res/layout/preference_dialog_library_categories.xml @@ -0,0 +1,11 @@ + + + + diff --git a/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml new file mode 100644 index 00000000..3446e8b8 --- /dev/null +++ b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml @@ -0,0 +1,45 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1befbdde..0c8fbb68 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -140,6 +140,7 @@ Entfernen Umbenennen Erstellen + Zurücksetzen %1$d ausgewählt Hauptfarbe Akzentfarbe @@ -284,4 +285,8 @@ Der Inhalt der Ordner auf der Blacklist wird in deiner Bibliothek verborgen. Künstler-Bild zurücksetzen Künstler-Bild festlegen + Bibliothek + Anzeige und Anordnung der einzelnen Kategorien festlegen. + Kategorien bearbeiten + Zumindest eine Kategorie muss aktiv sein. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0a05e391..0fd77e6f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -141,6 +141,7 @@ Remove Rename Create + Reset %1$d selected Primary color Accent color @@ -294,4 +295,8 @@ The content of blacklisted folders is hidden from your library. Reset artist image Set artist image + Library categories + Configure visibility and order of library categories. + Edit categories + At least one category must be enabled. diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index ed43ede6..56816287 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -20,6 +20,11 @@ android:positiveButtonText="@null" android:title="@string/pref_title_general_theme" /> + + From 7b1f9635a5fc2d80e425bdbf4fbc47f9ffa8b033 Mon Sep 17 00:00:00 2001 From: doompadee <31240866+doompadee@users.noreply.github.com> Date: Sat, 23 Dec 2017 17:28:53 +0100 Subject: [PATCH 03/11] Use resource key from catgory --- .../adapter/MusicLibraryPagerAdapter.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java index 39763fda..35b98cce 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java @@ -49,7 +49,7 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter { Holder holder = new Holder(); holder.mClassName = fragment.getFragmentClass().getName(); holder.title = mContext.getResources() - .getString(fragment.getResourceKey()) + .getString(category.id.key) .toUpperCase(Locale.getDefault()); mHolderList.add(holder); } @@ -149,28 +149,22 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter { } public enum MusicFragments { - SONGS(SongsFragment.class, R.string.songs), - ALBUMS(AlbumsFragment.class, R.string.albums), - ARTISTS(ArtistsFragment.class, R.string.artists), - GENRES(GenresFragment.class, R.string.genres), - PLAYLISTS(PlaylistsFragment.class, R.string.playlists); + SONGS(SongsFragment.class), + ALBUMS(AlbumsFragment.class), + ARTISTS(ArtistsFragment.class), + GENRES(GenresFragment.class), + PLAYLISTS(PlaylistsFragment.class); private final Class mFragmentClass; - private final int key; - MusicFragments(final Class fragmentClass, int key) { + MusicFragments(final Class fragmentClass) { mFragmentClass = fragmentClass; - this.key = key; } public Class getFragmentClass() { 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++) { From 6bf7697e67613a014a345b8e8583afd7a20319e5 Mon Sep 17 00:00:00 2001 From: doompadee <31240866+doompadee@users.noreply.github.com> Date: Sun, 24 Dec 2017 07:42:13 +0100 Subject: [PATCH 04/11] Make drag handle area bigger --- .../gramophone/adapter/CategoryAdapter.java | 15 +++++++-------- ...ference_dialog_library_categories_listitem.xml | 8 ++++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java index 7c0cb9cb..d7d058d1 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java @@ -117,16 +117,15 @@ public class CategoryAdapter extends RecyclerView.Adapter + android:minWidth="48dp" + android:minHeight="40dp" /> \ No newline at end of file From e2178fd7d8721d2b6374008c6acb4f6dcf1f7bee Mon Sep 17 00:00:00 2001 From: doompadee <31240866+doompadee@users.noreply.github.com> Date: Sun, 24 Dec 2017 13:42:05 +0100 Subject: [PATCH 05/11] Remove leftover comment --- .../res/layout/preference_dialog_library_categories_listitem.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml index e2f9a3d4..7f374883 100644 --- a/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml +++ b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml @@ -42,4 +42,3 @@ android:minWidth="48dp" android:minHeight="40dp" /> - \ No newline at end of file From 36095431afac78000ce373999d4167a55b092080 Mon Sep 17 00:00:00 2001 From: doompadee <31240866+doompadee@users.noreply.github.com> Date: Sun, 24 Dec 2017 14:46:44 +0100 Subject: [PATCH 06/11] Another leftover removal --- .../gramophone/adapter/CategoryAdapter.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java index d7d058d1..af594f0c 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java @@ -87,12 +87,6 @@ public class CategoryAdapter extends RecyclerView.Adapter copy(ArrayList categories) { ArrayList result = new ArrayList<>(); for (Category category : categories) { @@ -184,10 +176,6 @@ public class CategoryAdapter extends RecyclerView.Adapter Date: Sun, 24 Dec 2017 23:34:55 +0100 Subject: [PATCH 07/11] Merge with upstream and more cleanup --- .../gramophone/adapter/CategoryAdapter.java | 141 +++--------------- .../preferences/LibraryPreferenceDialog.java | 35 +---- .../gramophone/util/PreferenceUtil.java | 24 +-- 3 files changed, 37 insertions(+), 163 deletions(-) diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java index af594f0c..eacff7ca 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java @@ -1,20 +1,6 @@ package com.kabouzeid.gramophone.adapter; -import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.os.Build; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; -import android.support.v4.graphics.drawable.DrawableCompat; +import android.annotation.SuppressLint; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; import android.view.LayoutInflater; @@ -24,117 +10,46 @@ import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.TextView; -import com.kabouzeid.appthemehelper.ThemeStore; import com.kabouzeid.gramophone.R; -import com.kabouzeid.gramophone.util.SwipeAndDragHelper; import com.kabouzeid.gramophone.model.Category; +import com.kabouzeid.gramophone.util.SwipeAndDragHelper; import java.util.ArrayList; -public class CategoryAdapter extends RecyclerView.Adapter implements SwipeAndDragHelper.ActionCompletionContract { +public class CategoryAdapter extends RecyclerView.Adapter implements SwipeAndDragHelper.ActionCompletionContract { private ArrayList categories; private ItemTouchHelper touchHelper; - private ColorStateList color; - public CategoryAdapter(ArrayList categories, ColorStateList color) { - this.categories = copy(categories); - this.color = color; + public CategoryAdapter(ArrayList categories) { + this.categories = categories; } @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public CategoryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.preference_dialog_library_categories_listitem, parent, false); - return new CategoryViewHolder(view); + return new ViewHolder(view); } + @SuppressLint("ClickableViewAccessibility") @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + public void onBindViewHolder(CategoryAdapter.ViewHolder holder, int position) { Category category = categories.get(position); - CategoryViewHolder h = (CategoryViewHolder) holder; - h.checkBox.setChecked(category.visible); - h.title.setText(h.title.getResources().getString(category.id.key)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { - h.checkBox.setButtonTintList(color); - } else { - Drawable checkDrawable = - ContextCompat.getDrawable(h.checkBox.getContext(), R.drawable.abc_btn_check_material); - Drawable drawable = DrawableCompat.wrap(checkDrawable); - DrawableCompat.setTintList(drawable, color); - h.checkBox.setButtonDrawable(drawable); - } + holder.checkBox.setChecked(category.visible); + holder.title.setText(holder.title.getResources().getString(category.id.key)); - h.checkBox.setOnClickListener((view) -> { - h.checkBox.setChecked(category.visible = !category.visible); - notifyDataSetChanged(); - } - ); + holder.itemView.setOnClickListener(v -> { + category.visible = !category.visible; + holder.checkBox.setChecked(category.visible); + }); - h.title.setOnClickListener((view) -> { - h.checkBox.setChecked(category.visible = !category.visible); - notifyDataSetChanged(); - } - ); - - h.dragHandle.setOnTouchListener((view, event) -> { + holder.dragView.setOnTouchListener((view, event) -> { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { - touchHelper.startDrag(h); + touchHelper.startDrag(holder); } return false; } ); - - Context context = h.dragHandle.getContext(); - int backgroundColor = ThemeStore.textColorSecondary(context); - int borderColor = ThemeStore.textColorSecondaryInverse(context); - h.dragHandle.setBackground(new DragHandle(h.dragHandle.getResources().getDisplayMetrics().density, backgroundColor, borderColor)); - } - - private static class DragHandle extends Drawable { - private float density; - private Paint shape; - private Paint outline; - - public DragHandle(float density, int color, int borderColor) { - this.shape = new Paint(); - this.shape.setStyle(Paint.Style.FILL); - this.shape.setColor(color); - - this.outline = new Paint(); - this.outline.setAntiAlias(true); - this.outline.setStyle(Paint.Style.STROKE); - this.outline.setColor(borderColor); - - this.density = density; - } - - @Override - public void draw(@NonNull Canvas canvas) { - Rect bounds = getBounds(); - float width = 15 * density; - float left = bounds.centerX() - width / 2; - float top = bounds.top + bounds.centerY() - 3 * density; - canvas.save(); - canvas.drawRect(left, top, left + width, top + 2 * density, shape); - canvas.drawRect(left, top, left + width, top + 2 * density, outline); - canvas.translate(0, (density * 2) * 2); - canvas.drawRect(left, top, left + width, top + 2 * density, shape); - canvas.drawRect(left, top, left + width, top + 2 * density, outline); - canvas.restore(); - } - - @Override - public void setAlpha(int i) { - } - - @Override - public void setColorFilter(@Nullable ColorFilter filter) { - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } } @Override @@ -142,13 +57,9 @@ public class CategoryAdapter extends RecyclerView.Adapter categories) { - this.categories = copy(categories); + this.categories = categories; notifyDataSetChanged(); } @@ -168,24 +79,16 @@ public class CategoryAdapter extends RecyclerView.Adapter copy(ArrayList categories) { - ArrayList result = new ArrayList<>(); - for (Category category : categories) { - result.add(new Category(category)); - } - return result; - } - - private static class CategoryViewHolder extends RecyclerView.ViewHolder { + static class ViewHolder extends RecyclerView.ViewHolder { public CheckBox checkBox; public TextView title; - public View dragHandle; + public View dragView; - public CategoryViewHolder(View view) { + public ViewHolder(View view) { super(view); checkBox = view.findViewById(R.id.checkbox); title = view.findViewById(R.id.title); - dragHandle = view.findViewById(R.id.drag_handle); + dragView = view.findViewById(R.id.drag_view); } } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java index 54774614..62caf782 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java +++ b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java @@ -1,7 +1,6 @@ package com.kabouzeid.gramophone.preferences; import android.app.Dialog; -import android.content.res.ColorStateList; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; @@ -11,10 +10,7 @@ import android.support.v7.widget.helper.ItemTouchHelper; import android.view.LayoutInflater; import android.view.View; -import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; -import com.afollestad.materialdialogs.util.DialogUtils; -import com.kabouzeid.appthemehelper.ThemeStore; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.adapter.CategoryAdapter; import com.kabouzeid.gramophone.model.Category; @@ -35,10 +31,10 @@ public class LibraryPreferenceDialog extends DialogFragment { LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.preference_dialog_library_categories, null); - final ArrayList categories = PreferenceUtil.getInstance(getContext()).getLibraryCategories(); + ArrayList categories = PreferenceUtil.getInstance(getContext()).getLibraryCategories(); RecyclerView categoriesView = view.findViewById(R.id.recycler_view); categoriesView.setLayoutManager(new LinearLayoutManager(getActivity())); - final CategoryAdapter adapter = new CategoryAdapter(categories, getCheckboxColors()); + CategoryAdapter adapter = new CategoryAdapter(categories); SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(adapter); ItemTouchHelper touchHelper = new ItemTouchHelper(swipeAndDragHelper); adapter.setTouchHelper(touchHelper); @@ -59,10 +55,10 @@ public class LibraryPreferenceDialog extends DialogFragment { .onPositive((dialog13, action) -> { if (!updateCategories(adapter.getCategories())) { new MaterialDialog.Builder(getContext()) - .title(R.string.edit_categories) - .content(R.string.at_least_one_category_must_be_enabled) - .positiveText(android.R.string.ok) - .show(); + .title(R.string.edit_categories) + .content(R.string.at_least_one_category_must_be_enabled) + .positiveText(android.R.string.ok) + .show(); } else { dismiss(); } @@ -84,25 +80,8 @@ public class LibraryPreferenceDialog extends DialogFragment { int selected = 0; for (Category category : categories) { if (category.visible) - selected ++; + selected++; } return selected; } - - private ColorStateList getCheckboxColors() { - int disabledColor = DialogUtils.getDisabledColor(getContext()); - return new ColorStateList( - new int[][] { - new int[] {android.R.attr.state_enabled, -android.R.attr.state_checked}, - new int[] {android.R.attr.state_enabled, android.R.attr.state_checked}, - new int[] {-android.R.attr.state_enabled, -android.R.attr.state_checked}, - new int[] {-android.R.attr.state_enabled, android.R.attr.state_checked} - }, - new int[] { - DialogUtils.resolveColor(getContext(), R.attr.colorControlNormal), - ThemeStore.accentColor(getContext()), - disabledColor, - disabledColor - }); - } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java index 18af25a2..3c31482c 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java @@ -466,24 +466,16 @@ public final class PreferenceUtil { return result; } - return LibraryCategories.DEFAULTS; + return getDefaultLibraryCategories(); } public ArrayList getDefaultLibraryCategories() { - return LibraryCategories.DEFAULTS; - } - - private static class LibraryCategories { - public final static ArrayList DEFAULTS = getDefaults(); - - private static ArrayList getDefaults() { - ArrayList 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; - } + ArrayList 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; } } From 46a60e1ae80199e392587b32d0a15c240cb63e72 Mon Sep 17 00:00:00 2001 From: doompadee <31240866+doompadee@users.noreply.github.com> Date: Sun, 24 Dec 2017 23:52:55 +0100 Subject: [PATCH 08/11] Merge with upstream --- ...nce_dialog_library_categories_listitem.xml | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml index 7f374883..d76d4deb 100644 --- a/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml +++ b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml @@ -4,41 +4,53 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?selectableItemBackground" android:descendantFocusability="blocksDescendants" android:focusable="true" - android:minHeight="48dp" + android:foreground="?attr/rectSelector" + android:minHeight="@dimen/md_listitem_height" android:orientation="horizontal" - android:paddingEnd="24dp" - android:paddingLeft="24dp" - android:paddingRight="24dp" - android:paddingStart="24dp"> + android:paddingEnd="@dimen/md_dialog_frame_margin" + android:paddingLeft="@dimen/md_dialog_frame_margin" + android:paddingRight="@dimen/md_dialog_frame_margin" + android:paddingStart="@dimen/md_dialog_frame_margin" + tools:gravity="start|center_vertical"> - + android:focusable="false" + android:gravity="center_vertical" /> - + android:minHeight="@dimen/md_listitem_height" + android:tint="?attr/iconColor" + android:tintMode="src_in" + app:srcCompat="@drawable/ic_drag_vertical_white_24dp" + tools:ignore="ContentDescription" /> + From 30dd66e788da6d47fa76e26902ad1b0b01231750 Mon Sep 17 00:00:00 2001 From: Karim Abou Zeid Date: Tue, 26 Dec 2017 00:05:01 +0100 Subject: [PATCH 09/11] Clean up --- .../gramophone/adapter/CategoryAdapter.java | 15 +++++++++-- .../preferences/LibraryPreferenceDialog.java | 27 ++++++------------- .../gramophone/util/PreferenceUtil.java | 7 +++-- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java index eacff7ca..8f19450f 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java @@ -39,8 +39,10 @@ public class CategoryAdapter extends RecyclerView.Adapter { - category.visible = !category.visible; - holder.checkBox.setChecked(category.visible); + if (!(category.visible && isLastCheckedCategory(category))) { + category.visible = !category.visible; + holder.checkBox.setChecked(category.visible); + } }); holder.dragView.setOnTouchListener((view, event) -> { @@ -79,6 +81,15 @@ public class CategoryAdapter extends RecyclerView.Adapter { + .onNeutral((dialog, action) -> { adapter.setCategories(PreferenceUtil.getInstance(getContext()).getDefaultLibraryCategories()); }) - .onNegative((dialog12, action) -> dismiss()) - .onPositive((dialog13, action) -> { - if (!updateCategories(adapter.getCategories())) { - new MaterialDialog.Builder(getContext()) - .title(R.string.edit_categories) - .content(R.string.at_least_one_category_must_be_enabled) - .positiveText(android.R.string.ok) - .show(); - } else { - dismiss(); - } + .onNegative((dialog, action) -> dismiss()) + .onPositive((dialog, action) -> { + updateCategories(adapter.getCategories()); + dismiss(); }) .build(); - - return dialog; } - private boolean updateCategories(ArrayList categories) { - if (getSelected(categories) == 0) return false; + private void updateCategories(ArrayList categories) { + if (getSelected(categories) == 0) return; PreferenceUtil.getInstance(getContext()).setLibraryCategories(categories); - - return true; } private int getSelected(ArrayList categories) { diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java index 3c31482c..9cc08451 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java @@ -7,6 +7,7 @@ import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.StyleRes; +import com.google.gson.Gson; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.helper.SortOrder; import com.kabouzeid.gramophone.model.Category; @@ -14,13 +15,11 @@ import com.kabouzeid.gramophone.ui.fragments.mainactivity.folders.FoldersFragmen import com.kabouzeid.gramophone.ui.fragments.player.NowPlayingScreen; import java.io.File; -import java.util.Collections; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.Set; -import com.google.gson.Gson; - public final class PreferenceUtil { public static final String GENERAL_THEME = "general_theme"; public static final String DEFAULT_START_PAGE = "default_start_page"; @@ -449,7 +448,7 @@ public final class PreferenceUtil { SharedPreferences.Editor editor = mPreferences.edit(); editor.putStringSet(LIBRARY_CATEGORIES, data); - editor.commit(); + editor.apply(); } public ArrayList getLibraryCategories() { From 739e565bc4815119b774235a60a8780f3745a4aa Mon Sep 17 00:00:00 2001 From: Karim Abou Zeid Date: Tue, 26 Dec 2017 22:35:07 +0100 Subject: [PATCH 10/11] Clean up --- ...yAdapter.java => CategoryInfoAdapter.java} | 56 ++++++++-------- .../adapter/MusicLibraryPagerAdapter.java | 16 ++--- .../kabouzeid/gramophone/model/Category.java | 65 ------------------- .../gramophone/model/CategoryInfo.java | 27 ++++++++ .../preferences/LibraryPreferenceDialog.java | 42 +++++------- .../mainactivity/library/LibraryFragment.java | 2 +- .../gramophone/util/PreferenceUtil.java | 58 ++++++++--------- 7 files changed, 107 insertions(+), 159 deletions(-) rename app/src/main/java/com/kabouzeid/gramophone/adapter/{CategoryAdapter.java => CategoryInfoAdapter.java} (51%) delete mode 100644 app/src/main/java/com/kabouzeid/gramophone/model/Category.java create mode 100644 app/src/main/java/com/kabouzeid/gramophone/model/CategoryInfo.java diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryInfoAdapter.java similarity index 51% rename from app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java rename to app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryInfoAdapter.java index 8f19450f..7f412e71 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryInfoAdapter.java @@ -11,37 +11,39 @@ import android.widget.CheckBox; import android.widget.TextView; import com.kabouzeid.gramophone.R; -import com.kabouzeid.gramophone.model.Category; +import com.kabouzeid.gramophone.model.CategoryInfo; import com.kabouzeid.gramophone.util.SwipeAndDragHelper; import java.util.ArrayList; -public class CategoryAdapter extends RecyclerView.Adapter implements SwipeAndDragHelper.ActionCompletionContract { - private ArrayList categories; +public class CategoryInfoAdapter extends RecyclerView.Adapter implements SwipeAndDragHelper.ActionCompletionContract { + private ArrayList categoryInfos; private ItemTouchHelper touchHelper; - public CategoryAdapter(ArrayList categories) { - this.categories = categories; + public CategoryInfoAdapter(ArrayList categoryInfos) { + this.categoryInfos = categoryInfos; + SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(this); + touchHelper = new ItemTouchHelper(swipeAndDragHelper); } @Override - public CategoryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public CategoryInfoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.preference_dialog_library_categories_listitem, parent, false); return new ViewHolder(view); } @SuppressLint("ClickableViewAccessibility") @Override - public void onBindViewHolder(CategoryAdapter.ViewHolder holder, int position) { - Category category = categories.get(position); + public void onBindViewHolder(CategoryInfoAdapter.ViewHolder holder, int position) { + CategoryInfo categoryInfo = categoryInfos.get(position); - holder.checkBox.setChecked(category.visible); - holder.title.setText(holder.title.getResources().getString(category.id.key)); + holder.checkBox.setChecked(categoryInfo.visible); + holder.title.setText(holder.title.getResources().getString(categoryInfo.category.stringRes)); holder.itemView.setOnClickListener(v -> { - if (!(category.visible && isLastCheckedCategory(category))) { - category.visible = !category.visible; - holder.checkBox.setChecked(category.visible); + if (!(categoryInfo.visible && isLastCheckedCategory(categoryInfo))) { + categoryInfo.visible = !categoryInfo.visible; + holder.checkBox.setChecked(categoryInfo.visible); } }); @@ -56,35 +58,35 @@ public class CategoryAdapter extends RecyclerView.Adapter categories) { - this.categories = categories; + public void setCategoryInfos(ArrayList categoryInfos) { + this.categoryInfos = categoryInfos; notifyDataSetChanged(); } @Override public void onViewMoved(int oldPosition, int newPosition) { - Category category = categories.get(oldPosition); - categories.remove(oldPosition); - categories.add(newPosition, category); + CategoryInfo categoryInfo = categoryInfos.get(oldPosition); + categoryInfos.remove(oldPosition); + categoryInfos.add(newPosition, categoryInfo); notifyItemMoved(oldPosition, newPosition); } - public void setTouchHelper(ItemTouchHelper touchHelper) { - this.touchHelper = touchHelper; + public void attachToRecyclerView(RecyclerView recyclerView) { + touchHelper.attachToRecyclerView(recyclerView); } - public ArrayList getCategories() { - return categories; + public ArrayList getCategoryInfos() { + return categoryInfos; } - private boolean isLastCheckedCategory(Category category) { - if (category.visible) { - for (Category c : categories) { - if (c != category && c.visible) return false; + private boolean isLastCheckedCategory(CategoryInfo categoryInfo) { + if (categoryInfo.visible) { + for (CategoryInfo c : categoryInfos) { + if (c != categoryInfo && c.visible) return false; } } return true; diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java index 35b98cce..9929a0c6 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/MusicLibraryPagerAdapter.java @@ -9,8 +9,7 @@ import android.support.v4.app.FragmentPagerAdapter; import android.util.SparseArray; import android.view.ViewGroup; -import com.kabouzeid.gramophone.R; -import com.kabouzeid.gramophone.model.Category; +import com.kabouzeid.gramophone.model.CategoryInfo; 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.GenresFragment; @@ -36,20 +35,19 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter { public MusicLibraryPagerAdapter(@NonNull final Context context, final FragmentManager fragmentManager) { super(fragmentManager); mContext = context; - setCategories(PreferenceUtil.getInstance(context).getLibraryCategories()); + setCategoryInfos(PreferenceUtil.getInstance(context).getLibraryCategoryInfos()); } - public void setCategories(@NonNull ArrayList categories) { + public void setCategoryInfos(@NonNull ArrayList categoryInfos) { mHolderList.clear(); - for (int i = 0, size = categories.size(); i < size; i++) { - Category category = categories.get(i); - if (category.visible) { - MusicFragments fragment = MusicFragments.valueOf(category.id.toString()); + for (CategoryInfo categoryInfo : categoryInfos) { + if (categoryInfo.visible) { + MusicFragments fragment = MusicFragments.valueOf(categoryInfo.category.toString()); Holder holder = new Holder(); holder.mClassName = fragment.getFragmentClass().getName(); holder.title = mContext.getResources() - .getString(category.id.key) + .getString(categoryInfo.category.stringRes) .toUpperCase(Locale.getDefault()); mHolderList.add(holder); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/Category.java b/app/src/main/java/com/kabouzeid/gramophone/model/Category.java deleted file mode 100644 index 87013376..00000000 --- a/app/src/main/java/com/kabouzeid/gramophone/model/Category.java +++ /dev/null @@ -1,65 +0,0 @@ -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; - } - } -} diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/CategoryInfo.java b/app/src/main/java/com/kabouzeid/gramophone/model/CategoryInfo.java new file mode 100644 index 00000000..109f4352 --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/model/CategoryInfo.java @@ -0,0 +1,27 @@ +package com.kabouzeid.gramophone.model; + +import com.kabouzeid.gramophone.R; + +public class CategoryInfo { + public Category category; + public boolean visible; + + public CategoryInfo(Category category, boolean visible) { + this.category = category; + this.visible = visible; + } + + public enum Category { + SONGS(R.string.songs), + ALBUMS(R.string.albums), + ARTISTS(R.string.artists), + GENRES(R.string.genres), + PLAYLISTS(R.string.playlists); + + public final int stringRes; + + Category(int stringRes) { + this.stringRes = stringRes; + } + } +} diff --git a/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java index e2b90321..23191dd3 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java +++ b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java @@ -6,16 +6,13 @@ import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.helper.ItemTouchHelper; -import android.view.LayoutInflater; import android.view.View; import com.afollestad.materialdialogs.MaterialDialog; import com.kabouzeid.gramophone.R; -import com.kabouzeid.gramophone.adapter.CategoryAdapter; -import com.kabouzeid.gramophone.model.Category; +import com.kabouzeid.gramophone.adapter.CategoryInfoAdapter; +import com.kabouzeid.gramophone.model.CategoryInfo; import com.kabouzeid.gramophone.util.PreferenceUtil; -import com.kabouzeid.gramophone.util.SwipeAndDragHelper; import java.util.ArrayList; @@ -28,18 +25,15 @@ public class LibraryPreferenceDialog extends DialogFragment { @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - LayoutInflater inflater = getActivity().getLayoutInflater(); - View view = inflater.inflate(R.layout.preference_dialog_library_categories, null); + View view = getActivity().getLayoutInflater().inflate(R.layout.preference_dialog_library_categories, null); - ArrayList categories = PreferenceUtil.getInstance(getContext()).getLibraryCategories(); - RecyclerView categoriesView = view.findViewById(R.id.recycler_view); - categoriesView.setLayoutManager(new LinearLayoutManager(getActivity())); - CategoryAdapter adapter = new CategoryAdapter(categories); - SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(adapter); - ItemTouchHelper touchHelper = new ItemTouchHelper(swipeAndDragHelper); - adapter.setTouchHelper(touchHelper); - categoriesView.setAdapter(adapter); - touchHelper.attachToRecyclerView(categoriesView); + CategoryInfoAdapter adapter = new CategoryInfoAdapter(PreferenceUtil.getInstance(getContext()).getLibraryCategoryInfos()); + + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + recyclerView.setAdapter(adapter); + + adapter.attachToRecyclerView(recyclerView); return new MaterialDialog.Builder(getContext()) .title(R.string.library_categories) @@ -48,27 +42,25 @@ public class LibraryPreferenceDialog extends DialogFragment { .negativeText(android.R.string.cancel) .neutralText(R.string.reset_action) .autoDismiss(false) - .onNeutral((dialog, action) -> { - adapter.setCategories(PreferenceUtil.getInstance(getContext()).getDefaultLibraryCategories()); - }) + .onNeutral((dialog, action) -> adapter.setCategoryInfos(PreferenceUtil.getInstance(getContext()).getDefaultLibraryCategoryInfos())) .onNegative((dialog, action) -> dismiss()) .onPositive((dialog, action) -> { - updateCategories(adapter.getCategories()); + updateCategories(adapter.getCategoryInfos()); dismiss(); }) .build(); } - private void updateCategories(ArrayList categories) { + private void updateCategories(ArrayList categories) { if (getSelected(categories) == 0) return; - PreferenceUtil.getInstance(getContext()).setLibraryCategories(categories); + PreferenceUtil.getInstance(getContext()).setLibraryCategoryInfos(categories); } - private int getSelected(ArrayList categories) { + private int getSelected(ArrayList categories) { int selected = 0; - for (Category category : categories) { - if (category.visible) + for (CategoryInfo categoryInfo : categories) { + if (categoryInfo.visible) selected++; } return selected; diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java index 536102ee..5dbdbd7e 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/mainactivity/library/LibraryFragment.java @@ -98,7 +98,7 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { if (PreferenceUtil.LIBRARY_CATEGORIES.equals(key)) { Fragment current = getCurrentFragment(); - pagerAdapter.setCategories(PreferenceUtil.getInstance(getActivity()).getLibraryCategories()); + pagerAdapter.setCategoryInfos(PreferenceUtil.getInstance(getActivity()).getLibraryCategoryInfos()); pager.setOffscreenPageLimit(pagerAdapter.getCount() - 1); int position = pagerAdapter.getItemPosition(current); pager.setCurrentItem(position > -1 ? position : 0); diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java index 9cc08451..73b5c25a 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/PreferenceUtil.java @@ -8,17 +8,17 @@ import android.support.annotation.NonNull; import android.support.annotation.StyleRes; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.helper.SortOrder; -import com.kabouzeid.gramophone.model.Category; +import com.kabouzeid.gramophone.model.CategoryInfo; import com.kabouzeid.gramophone.ui.fragments.mainactivity.folders.FoldersFragment; import com.kabouzeid.gramophone.ui.fragments.player.NowPlayingScreen; import java.io.File; +import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; public final class PreferenceUtil { public static final String GENERAL_THEME = "general_theme"; @@ -435,46 +435,40 @@ public final class PreferenceUtil { return mPreferences.getBoolean(INITIALIZED_BLACKLIST, false); } - public void setLibraryCategories(ArrayList categories) { + public void setLibraryCategoryInfos(ArrayList categories) { Gson gson = new Gson(); + Type collectionType = new TypeToken>() { + }.getType(); - Set 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); + final SharedPreferences.Editor editor = mPreferences.edit(); + editor.putString(LIBRARY_CATEGORIES, gson.toJson(categories, collectionType)); editor.apply(); } - public ArrayList getLibraryCategories() { - Set data = mPreferences.getStringSet(LIBRARY_CATEGORIES, null); + public ArrayList getLibraryCategoryInfos() { + String data = mPreferences.getString(LIBRARY_CATEGORIES, null); if (data != null) { Gson gson = new Gson(); - ArrayList result = new ArrayList<>(Collections.nCopies(data.size(), (Category) null)); + Type collectionType = new TypeToken>() { + }.getType(); - for (String json : data) { - Category category = gson.fromJson(json, Category.class); - result.set(category.index, category); + try { + return gson.fromJson(data, collectionType); + } catch (JsonSyntaxException e) { + e.printStackTrace(); } - - return result; } - return getDefaultLibraryCategories(); + return getDefaultLibraryCategoryInfos(); } - public ArrayList getDefaultLibraryCategories() { - ArrayList 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; + public ArrayList getDefaultLibraryCategoryInfos() { + ArrayList defaultCategoryInfos = new ArrayList<>(5); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.SONGS, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.ALBUMS, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.ARTISTS, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.GENRES, true)); + defaultCategoryInfos.add(new CategoryInfo(CategoryInfo.Category.PLAYLISTS, true)); + return defaultCategoryInfos; } } From df5d4cd984d4a1ee46d925d5b5806934b37d514f Mon Sep 17 00:00:00 2001 From: Karim Abou Zeid Date: Tue, 26 Dec 2017 22:39:44 +0100 Subject: [PATCH 11/11] Explicit gson dependency --- app/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/app/build.gradle b/app/build.gradle index 3132c5f6..3ea1a445 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -125,6 +125,7 @@ dependencies { implementation('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar') { transitive = true } + implementation 'com.google.code.gson:gson:2.8.2' implementation 'com.crashlytics.sdk.android:crashlytics:2.8.0' implementation('com.crashlytics.sdk.android:answers:1.3.13@aar') { transitive = true