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..eacff7ca --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/CategoryAdapter.java @@ -0,0 +1,95 @@ +package com.kabouzeid.gramophone.adapter; + +import android.annotation.SuppressLint; +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.gramophone.R; +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 { + private ArrayList categories; + private ItemTouchHelper touchHelper; + + public CategoryAdapter(ArrayList categories) { + this.categories = categories; + } + + @Override + 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 ViewHolder(view); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void onBindViewHolder(CategoryAdapter.ViewHolder holder, int position) { + Category category = categories.get(position); + + holder.checkBox.setChecked(category.visible); + holder.title.setText(holder.title.getResources().getString(category.id.key)); + + holder.itemView.setOnClickListener(v -> { + category.visible = !category.visible; + holder.checkBox.setChecked(category.visible); + }); + + holder.dragView.setOnTouchListener((view, event) -> { + if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + touchHelper.startDrag(holder); + } + return false; + } + ); + } + + @Override + public int getItemCount() { + return categories.size(); + } + + + public void setCategories(ArrayList categories) { + this.categories = 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; + } + + static class ViewHolder extends RecyclerView.ViewHolder { + public CheckBox checkBox; + public TextView title; + public View dragView; + + public ViewHolder(View view) { + super(view); + checkBox = view.findViewById(R.id.checkbox); + title = view.findViewById(R.id.title); + dragView = view.findViewById(R.id.drag_view); + } + } +} + 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..35b98cce 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(category.id.key) + .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,16 +120,40 @@ 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), + SONGS(SongsFragment.class), + ALBUMS(AlbumsFragment.class), + ARTISTS(ArtistsFragment.class), GENRES(GenresFragment.class), - PLAYLIST(PlaylistsFragment.class); + PLAYLISTS(PlaylistsFragment.class); private final Class mFragmentClass; @@ -124,10 +164,25 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter { public Class getFragmentClass() { return mFragmentClass; } + + 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/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..62caf782 --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/preferences/LibraryPreferenceDialog.java @@ -0,0 +1,87 @@ +package com.kabouzeid.gramophone.preferences; + +import android.app.Dialog; +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.MaterialDialog; +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); + + 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); + + 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; + } +} 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/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..3c31482c 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,47 @@ 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 getDefaultLibraryCategories(); + } + + 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; + } } 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..d76d4deb --- /dev/null +++ b/app/src/main/res/layout/preference_dialog_library_categories_listitem.xml @@ -0,0 +1,56 @@ + + + + + + + + + + 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" /> + +