Merge branch 'arkon-genre-tweaks'

This commit is contained in:
Karim Abou Zeid 2017-12-18 20:11:07 +01:00
commit 723912d928
8 changed files with 125 additions and 94 deletions

View file

@ -56,9 +56,27 @@ public class GenreAdapter extends RecyclerView.Adapter<GenreAdapter.ViewHolder>
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final Genre genre = dataSet.get(position);
if (holder.getAdapterPosition() == getItemCount() - 1) {
if (holder.separator != null) {
holder.separator.setVisibility(View.GONE);
}
} else {
if (holder.separator != null) {
holder.separator.setVisibility(View.VISIBLE);
}
}
if (holder.shortSeparator != null) {
holder.shortSeparator.setVisibility(View.GONE);
}
if (holder.menu != null) {
holder.menu.setVisibility(View.GONE);
}
if (holder.title != null) {
holder.title.setText(genre.name);
}
if (holder.text != null) {
holder.text.setText(MusicUtil.getGenreInfoString(activity, genre));
}
}
@Override

View file

@ -2,13 +2,10 @@ package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore.Audio.Genres;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.model.Genre;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.PreferenceUtil;
@ -24,27 +21,16 @@ public class GenreLoader {
@NonNull
public static ArrayList<Song> getSongs(@NonNull final Context context, final int genreId) {
// The genres table only stores songs that have a genre specified,
// so we need to get songs without a genre a different way.
if (genreId == -1) {
return getSongsWithNoGenre(context);
}
return SongLoader.getSongs(makeGenreSongCursor(context, genreId));
}
@NonNull
private static ArrayList<Genre> getGenresFromCursor(@NonNull final Context context, @Nullable final Cursor cursor) {
final ArrayList<Genre> genres = new ArrayList<>();
if (hasSongsWithNoGenre(context)) {
genres.add(new Genre(context.getResources().getString(R.string.unknown_genre)));
}
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
genres.add(getGenreFromCursor(cursor));
genres.add(getGenreFromCursor(context, cursor));
} while (cursor.moveToNext());
}
cursor.close();
@ -53,42 +39,11 @@ public class GenreLoader {
}
@NonNull
private static Genre getGenreFromCursor(@NonNull final Cursor cursor) {
private static Genre getGenreFromCursor(@NonNull final Context context, @NonNull final Cursor cursor) {
final int id = cursor.getInt(0);
final String name = cursor.getString(1);
return new Genre(id, name);
}
@NonNull
private static ArrayList<Song> getSongsWithNoGenre(@NonNull final Context context) {
String selection = BaseColumns._ID + " NOT IN " +
"(SELECT " + Genres.Members.AUDIO_ID + " FROM audio_genres_map)";
return SongLoader.getSongs(SongLoader.makeSongCursor(context, selection, null));
}
private static boolean hasSongsWithNoGenre(@NonNull final Context context) {
final Cursor allSongsCursor = SongLoader.makeSongCursor(context, null, null);
final Cursor allSongsWithGenreCursor = makeAllSongsWithGenreCursor(context);
if (allSongsCursor == null || allSongsWithGenreCursor == null) {
return false;
}
final boolean hasSongsWithNoGenre = allSongsCursor.getCount() > allSongsWithGenreCursor.getCount();
allSongsCursor.close();
allSongsWithGenreCursor.close();
return hasSongsWithNoGenre;
}
@Nullable
private static Cursor makeAllSongsWithGenreCursor(@NonNull final Context context) {
try {
return context.getContentResolver().query(
Uri.parse("content://media/external/audio/genres/all/members"),
new String[]{Genres.Members.AUDIO_ID}, null, null, null);
} catch (SecurityException e) {
return null;
}
final int songs = getSongs(context, id).size();
return new Genre(id, name, songs);
}
@Nullable
@ -108,15 +63,11 @@ public class GenreLoader {
Genres._ID,
Genres.NAME
};
// Genres that actually have songs
final String selection = Genres._ID + " IN" +
" (SELECT " + Genres.Members.GENRE_ID + " FROM audio_genres_map WHERE " + Genres.Members.AUDIO_ID + " IN" +
" (SELECT " + Genres._ID + " FROM audio_meta WHERE " + SongLoader.BASE_SELECTION + "))";
try {
return context.getContentResolver().query(
Genres.EXTERNAL_CONTENT_URI,
projection, selection, null, PreferenceUtil.getInstance(context).getGenreSortOrder());
projection, null, null, PreferenceUtil.getInstance(context).getGenreSortOrder());
} catch (SecurityException e) {
return null;
}

View file

@ -6,16 +6,12 @@ import android.os.Parcelable;
public class Genre implements Parcelable {
public final int id;
public final String name;
public final int songCount;
public Genre(final int id, final String name) {
public Genre(final int id, final String name, final int songCount) {
this.id = id;
this.name = name;
}
// For unknown genre
public Genre(final String name) {
this.id = -1;
this.name = name;
this.songCount = songCount;
}
@Override
@ -26,13 +22,15 @@ public class Genre implements Parcelable {
Genre genre = (Genre) o;
if (id != genre.id) return false;
return name != null ? name.equals(genre.name) : genre.name == null;
if (!name.equals(genre.name)) return false;
return songCount == genre.songCount;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + name.hashCode();
result = 31 * result + songCount;
return result;
}
@ -41,6 +39,7 @@ public class Genre implements Parcelable {
return "Genre{" +
"id=" + id +
", name='" + name + '\'' +
", songCount=" + songCount + '\'' +
'}';
}
@ -53,11 +52,13 @@ public class Genre implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.name);
dest.writeInt(this.songCount);
}
protected Genre(Parcel in) {
this.id = in.readInt();
this.name = in.readString();
this.songCount = in.readInt();
}
public static final Creator<Genre> CREATOR = new Creator<Genre>() {

View file

@ -38,7 +38,7 @@ public class GenresFragment extends AbsLibraryPagerRecyclerViewFragment<GenreAda
@Override
protected GenreAdapter createAdapter() {
ArrayList<Genre> dataSet = getAdapter() == null ? new ArrayList<Genre>() : getAdapter().getDataSet();
return new GenreAdapter(getLibraryFragment().getMainActivity(), dataSet, R.layout.item_list_simple);
return new GenreAdapter(getLibraryFragment().getMainActivity(), dataSet, R.layout.item_list_no_image);
}
@Override

View file

@ -23,6 +23,7 @@ import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.Genre;
import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.model.lyrics.AbsSynchronizedLyrics;
@ -114,6 +115,13 @@ public class MusicUtil {
return albumCount + " " + albumString + "" + songCount + " " + songString;
}
@NonNull
public static String getGenreInfoString(@NonNull final Context context, @NonNull final Genre genre) {
int songCount = genre.songCount;
String songString = songCount == 1 ? context.getResources().getString(R.string.song) : context.getResources().getString(R.string.songs);
return songCount + " " + songString;
}
@NonNull
public static String getPlaylistInfoString(@NonNull final Context context, @NonNull List<Song> songs) {
final int songCount = songs.size();

View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="72dp"
android:foreground="?attr/rectSelector"
tools:ignore="UnusedAttribute">
<com.kabouzeid.gramophone.views.IconImageView
android:id="@+id/drag_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:layout_marginLeft="-8dp"
android:layout_marginStart="-8dp"
android:tint="?attr/iconColor"
android:tintMode="src_in"
android:visibility="gone"
app:srcCompat="@drawable/ic_drag_vertical_white_24dp"
tools:ignore="ContentDescription" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:orientation="vertical"
android:paddingEnd="0dp"
android:paddingLeft="16dp"
android:paddingRight="0dp"
android:paddingStart="16dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?android:textColorSecondary" />
</LinearLayout>
<com.kabouzeid.gramophone.views.IconImageView
android:id="@+id/menu"
style="@style/OverFlowButton"
android:layout_gravity="center_vertical"
tools:ignore="ContentDescription" />
</LinearLayout>
<View
android:id="@+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:background="?attr/dividerColor"
android:visibility="gone" />
<View
android:id="@+id/short_separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:layout_marginLeft="72dp"
android:layout_marginStart="72dp"
android:background="?attr/dividerColor" />
</FrameLayout>

View file

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="64dp"
android:foreground="?attr/rectSelector"
tools:ignore="UnusedAttribute">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:fontFamily="sans-serif"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
<View
android:id="@+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:background="?attr/dividerColor" />
</RelativeLayout>

View file

@ -42,7 +42,6 @@
<string name="album">Album</string>
<string name="artist">Artist</string>
<string name="genre">Genre</string>
<string name="unknown_genre">Unknown genre</string>
<string name="album_artist">Album artist</string>
<string name="year">Year</string>
<string name="track_hint">"Track (2 for track 2 or 3004 for CD3 track 4)"</string>