OSDN Git Service

Playlists: sort ignoring case
authorAlexander Martinz <amartinz@shiftphones.com>
Wed, 27 Feb 2019 13:32:00 +0000 (14:32 +0100)
committerMichael Bestas <mkbestas@lineageos.org>
Tue, 19 Mar 2019 20:56:33 +0000 (22:56 +0200)
Change-Id: I5c0a239afa7e033f0db5ec16845d942c2ecbeb15
Signed-off-by: Alexander Martinz <amartinz@shiftphones.com>
src/org/lineageos/eleven/model/Playlist.java
src/org/lineageos/eleven/ui/fragments/PlaylistFragment.java
src/org/lineageos/eleven/utils/MusicUtils.java

index 91d11df..60b2145 100644 (file)
@@ -1,20 +1,28 @@
 /*
  * Copyright (C) 2012 Andrew Neal
  * Copyright (C) 2014 The CyanogenMod Project
- * Licensed under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
- * or agreed to in writing, software distributed under the License is
- * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
+ * Copyright (C) 2019 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package org.lineageos.eleven.model;
 
+import android.support.annotation.NonNull;
 import android.text.TextUtils;
 
+import java.util.Comparator;
+
 /**
  * A class that represents a playlist.
  *
@@ -50,9 +58,6 @@ public class Playlist {
         mSongCount = songCount;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -63,9 +68,6 @@ public class Playlist {
         return result;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean equals(final Object obj) {
         if (this == obj) {
@@ -89,12 +91,13 @@ public class Playlist {
         return TextUtils.equals(mPlaylistName, other.mPlaylistName);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @NonNull
     @Override
     public String toString() {
-        return mPlaylistName;
+        return "Playlist[playlistId=" + mPlaylistId
+                + ", playlistName=" + mPlaylistName
+                + ", songCount=" + mSongCount
+                + "]";
     }
 
     /**
@@ -103,4 +106,11 @@ public class Playlist {
     public boolean isSmartPlaylist() {
         return mPlaylistId < 0;
     }
+
+    public static class IgnoreCaseComparator implements Comparator<Playlist> {
+        @Override
+        public int compare(Playlist p1, Playlist p2) {
+            return p1.mPlaylistName.compareToIgnoreCase(p2.mPlaylistName);
+        }
+    }
 }
index 20fdf39..3ce96f9 100644 (file)
@@ -1,19 +1,25 @@
 /*
  * Copyright (C) 2012 Andrew Neal
  * Copyright (C) 2014 The CyanogenMod Project
- * Licensed under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
- * or agreed to in writing, software distributed under the License is
- * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language
- * governing permissions and limitations under the License.
+ * Copyright (C) 2019 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package org.lineageos.eleven.ui.fragments;
 
 import android.os.Bundle;
+import android.support.annotation.NonNull;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.LoaderManager.LoaderCallbacks;
 import android.support.v4.content.Loader;
@@ -40,6 +46,8 @@ import org.lineageos.eleven.utils.PopupMenuHelper;
 import org.lineageos.eleven.widgets.IPopupMenuCallback;
 import org.lineageos.eleven.widgets.LoadingEmptyContainer;
 
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -75,6 +83,7 @@ public class PlaylistFragment extends MusicBrowserFragment implements
      * Empty constructor as per the {@link Fragment} documentation
      */
     public PlaylistFragment() {
+        // empty
     }
 
     @Override
@@ -82,9 +91,6 @@ public class PlaylistFragment extends MusicBrowserFragment implements
         return PagerAdapter.MusicFragments.PLAYLIST.ordinal();
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -97,24 +103,16 @@ public class PlaylistFragment extends MusicBrowserFragment implements
 
         // Create the adapter
         mAdapter = new PlaylistAdapter(getActivity());
-        mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
-            @Override
-            public void onPopupMenuClicked(View v, int position) {
-                mPopupMenuHelper.showPopupMenu(v, position);
-            }
-        });
+        mAdapter.setPopupMenuClickedListener((v, position) -> mPopupMenuHelper.showPopupMenu(v, position));
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+    public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container,
             final Bundle savedInstanceState) {
         // The View for the fragment's UI
-        final ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.list_base, null);
+        final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.list_base, container, false);
         // Initialize the list
-        mListView = (ListView)rootView.findViewById(R.id.list_base);
+        mListView = rootView.findViewById(R.id.list_base);
         // Set the data behind the grid
         mListView.setAdapter(mAdapter);
         // Release any references to the recycled Views
@@ -122,8 +120,7 @@ public class PlaylistFragment extends MusicBrowserFragment implements
         // Play the selected song
         mListView.setOnItemClickListener(this);
         // Setup the loading and empty state
-        mLoadingEmptyContainer =
-                (LoadingEmptyContainer)rootView.findViewById(R.id.loading_empty_container);
+        mLoadingEmptyContainer = rootView.findViewById(R.id.loading_empty_container);
         mListView.setEmptyView(mLoadingEmptyContainer);
 
         // Register the music status listener
@@ -139,10 +136,6 @@ public class PlaylistFragment extends MusicBrowserFragment implements
         ((BaseActivity)getActivity()).removeMusicStateListenerListener(this);
     }
 
-
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void onActivityCreated(final Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
@@ -152,9 +145,6 @@ public class PlaylistFragment extends MusicBrowserFragment implements
         initLoader(null, this);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void onItemClick(final AdapterView<?> parent, final View view, final int position,
             final long id) {
@@ -168,9 +158,7 @@ public class PlaylistFragment extends MusicBrowserFragment implements
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @NonNull
     @Override
     public Loader<List<Playlist>> onCreateLoader(final int id, final Bundle args) {
         // show the loading progress bar
@@ -178,39 +166,41 @@ public class PlaylistFragment extends MusicBrowserFragment implements
         return new PlaylistLoader(getActivity());
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public void onLoadFinished(final Loader<List<Playlist>> loader, final List<Playlist> data) {
-        // Check for any errors
+    public void onLoadFinished(@NonNull final Loader<List<Playlist>> loader, final List<Playlist> data) {
         if (data.isEmpty()) {
             mLoadingEmptyContainer.showNoResults();
             return;
         }
 
-        // Start fresh
+        // Start fresh, fill adapter with new data and create cache
         mAdapter.unload();
-        // Add the data to the adpater
+
+        // iterate through playlist list and add "smart playlists" first
+        final Iterator<Playlist> playlistIterator = data.listIterator();
+        while (playlistIterator.hasNext()) {
+            final Playlist playlist = playlistIterator.next();
+            if (playlist.mSongCount < 0) {
+                mAdapter.add(playlist);
+                playlistIterator.remove();
+            }
+        }
+
+        // after the "smart playlists" are added, sort and add remaining playlists
+        Collections.sort(data, new Playlist.IgnoreCaseComparator());
         for (final Playlist playlist : data) {
             mAdapter.add(playlist);
         }
-        // Build the cache
+
         mAdapter.buildCache();
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public void onLoaderReset(final Loader<List<Playlist>> loader) {
+    public void onLoaderReset(@NonNull final Loader<List<Playlist>> loader) {
         // Clear the data in the adapter
         mAdapter.unload();
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void restartLoader() {
         restartLoader(null, this);
@@ -221,9 +211,6 @@ public class PlaylistFragment extends MusicBrowserFragment implements
         restartLoader();
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void onMetaChanged() {
         // Nothing to do
index 766758f..92f9a44 100644 (file)
@@ -69,6 +69,8 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.WeakHashMap;
@@ -111,7 +113,7 @@ public final class MusicUtils {
      * @param callback The {@link ServiceConnection} to use
      * @return The new instance of {@link ServiceToken}
      */
-    public static final ServiceToken bindToService(final Context context,
+    public static ServiceToken bindToService(final Context context,
             final ServiceConnection callback) {
         Activity realActivity = ((Activity)context).getParent();
         if (realActivity == null) {
@@ -1438,6 +1440,9 @@ public final class MusicUtils {
                 }
             }
         }
+
+        // sort the list but ignore case
+        Collections.sort(menuItemMap, new IgnoreCaseComparator());
         return menuItemMap;
     }
 
@@ -1771,4 +1776,11 @@ public final class MusicUtils {
 
         return str.toString();
     }
+
+    public static class IgnoreCaseComparator implements Comparator<String> {
+        @Override
+        public int compare(String s1, String s2) {
+            return s1.compareToIgnoreCase(s2);
+        }
+    }
 }