Merged fastscroller from cabinet. Temporary fixed the wrong fab margins on KitKat and below caused by the google support design library. Added empty screens to Album Song and Artist views.

This commit is contained in:
Karim Abou Zeid 2015-06-02 21:27:02 +02:00
commit 3082ed1187
30 changed files with 483 additions and 195 deletions

View file

@ -27,14 +27,10 @@ android {
applicationId "com.kabouzeid.gramophone" applicationId "com.kabouzeid.gramophone"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 22 targetSdkVersion 22
versionCode 29 versionCode 30
versionName "0.9.13b DEV-3" versionName "0.9.14b DEV"
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes { buildTypes {
release { release {
minifyEnabled true minifyEnabled true

View file

@ -23,6 +23,8 @@ import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog; import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.OnUpdatedListener;
import com.kabouzeid.gramophone.interfaces.SelfUpdating;
import com.kabouzeid.gramophone.loader.AlbumLoader; import com.kabouzeid.gramophone.loader.AlbumLoader;
import com.kabouzeid.gramophone.loader.AlbumSongLoader; import com.kabouzeid.gramophone.loader.AlbumSongLoader;
import com.kabouzeid.gramophone.model.Album; import com.kabouzeid.gramophone.model.Album;
@ -47,12 +49,13 @@ import java.util.List;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album> { public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album> implements SelfUpdating {
public static final String TAG = AlbumAdapter.class.getSimpleName(); public static final String TAG = AlbumAdapter.class.getSimpleName();
private final AppCompatActivity activity; private final AppCompatActivity activity;
private boolean usePalette; private boolean usePalette;
private List<Album> dataSet; private List<Album> dataSet;
private OnUpdatedListener listener;
@Override @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
@ -130,6 +133,11 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
return songs; return songs;
} }
@Override
public void setOnUpdatedListener(OnUpdatedListener listener) {
this.listener = listener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
final ImageView albumArt; final ImageView albumArt;
final TextView title; final TextView title;
@ -193,6 +201,7 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
private void loadDataSet() { private void loadDataSet() {
dataSet = AlbumLoader.getAllAlbums(activity); dataSet = AlbumLoader.getAllAlbums(activity);
if (listener != null) listener.onUpdated(this);
} }
private void applyPalette(Bitmap bitmap, final TextView title, final TextView artist, final View footer) { private void applyPalette(Bitmap bitmap, final TextView title, final TextView artist, final View footer) {

View file

@ -17,6 +17,8 @@ import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog; import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.OnUpdatedListener;
import com.kabouzeid.gramophone.interfaces.SelfUpdating;
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistThumbnailUrlLoader; import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistThumbnailUrlLoader;
import com.kabouzeid.gramophone.loader.ArtistLoader; import com.kabouzeid.gramophone.loader.ArtistLoader;
import com.kabouzeid.gramophone.loader.ArtistSongLoader; import com.kabouzeid.gramophone.loader.ArtistSongLoader;
@ -36,9 +38,10 @@ import java.util.List;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist> { public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist> implements SelfUpdating {
protected final AppCompatActivity activity; protected final AppCompatActivity activity;
protected List<Artist> dataSet; protected List<Artist> dataSet;
private OnUpdatedListener listener;
public ArtistAdapter(AppCompatActivity activity, @Nullable CabHolder cabHolder) { public ArtistAdapter(AppCompatActivity activity, @Nullable CabHolder cabHolder) {
super(cabHolder, R.menu.menu_media_selection); super(cabHolder, R.menu.menu_media_selection);
@ -48,6 +51,7 @@ public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolde
private void loadDataSet() { private void loadDataSet() {
dataSet = ArtistLoader.getAllArtists(activity); dataSet = ArtistLoader.getAllArtists(activity);
if (listener != null) listener.onUpdated(this);
} }
@Override @Override
@ -112,6 +116,11 @@ public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolde
return songs; return songs;
} }
@Override
public void setOnUpdatedListener(OnUpdatedListener listener) {
this.listener = listener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
final TextView artistName; final TextView artistName;
final TextView artistInfo; final TextView artistInfo;

View file

@ -18,6 +18,8 @@ import com.kabouzeid.gramophone.dialogs.DeletePlaylistDialog;
import com.kabouzeid.gramophone.helper.MenuItemClickHelper; import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.OnUpdatedListener;
import com.kabouzeid.gramophone.interfaces.SelfUpdating;
import com.kabouzeid.gramophone.loader.PlaylistLoader; import com.kabouzeid.gramophone.loader.PlaylistLoader;
import com.kabouzeid.gramophone.loader.PlaylistSongLoader; import com.kabouzeid.gramophone.loader.PlaylistSongLoader;
import com.kabouzeid.gramophone.model.DataBaseChangedEvent; import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
@ -33,11 +35,12 @@ import java.util.List;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist> { public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist> implements SelfUpdating {
public static final String TAG = PlaylistAdapter.class.getSimpleName(); public static final String TAG = PlaylistAdapter.class.getSimpleName();
protected final AppCompatActivity activity; protected final AppCompatActivity activity;
protected List<Playlist> dataSet; protected List<Playlist> dataSet;
private OnUpdatedListener listener;
public PlaylistAdapter(AppCompatActivity activity, @Nullable CabHolder cabHolder) { public PlaylistAdapter(AppCompatActivity activity, @Nullable CabHolder cabHolder) {
super(cabHolder, R.menu.menu_playlists_selection); super(cabHolder, R.menu.menu_playlists_selection);
@ -47,6 +50,7 @@ public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewH
public void loadDataSet() { public void loadDataSet() {
dataSet = PlaylistLoader.getAllPlaylists(activity); dataSet = PlaylistLoader.getAllPlaylists(activity);
if (listener != null) listener.onUpdated(this);
} }
@Override @Override
@ -95,6 +99,11 @@ public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewH
return songs; return songs;
} }
@Override
public void setOnUpdatedListener(OnUpdatedListener listener) {
this.listener = listener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public final TextView playlistName; public final TextView playlistName;
private final View menu; private final View menu;

View file

@ -22,6 +22,8 @@ import com.kabouzeid.gramophone.dialogs.DeleteSongsDialog;
import com.kabouzeid.gramophone.helper.MenuItemClickHelper; import com.kabouzeid.gramophone.helper.MenuItemClickHelper;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote; import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.OnUpdatedListener;
import com.kabouzeid.gramophone.interfaces.SelfUpdating;
import com.kabouzeid.gramophone.loader.SongLoader; import com.kabouzeid.gramophone.loader.SongLoader;
import com.kabouzeid.gramophone.model.DataBaseChangedEvent; import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.Song;
@ -37,7 +39,7 @@ import java.util.ArrayList;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song> implements MaterialCab.Callback { public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song> implements MaterialCab.Callback, SelfUpdating {
public static final String TAG = AlbumSongAdapter.class.getSimpleName(); public static final String TAG = AlbumSongAdapter.class.getSimpleName();
private static final int SHUFFLE_BUTTON = 0; private static final int SHUFFLE_BUTTON = 0;
@ -45,6 +47,7 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
protected final AppCompatActivity activity; protected final AppCompatActivity activity;
protected ArrayList<Song> dataSet; protected ArrayList<Song> dataSet;
private OnUpdatedListener listener;
public SongAdapter(AppCompatActivity activity, CabHolder cabHolder) { public SongAdapter(AppCompatActivity activity, CabHolder cabHolder) {
super(cabHolder, R.menu.menu_media_selection); super(cabHolder, R.menu.menu_media_selection);
@ -54,6 +57,7 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
private void loadDataSet() { private void loadDataSet() {
dataSet = SongLoader.getAllSongs(activity); dataSet = SongLoader.getAllSongs(activity);
if (listener != null) listener.onUpdated(this);
} }
@Override @Override
@ -101,7 +105,8 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
@Override @Override
public int getItemCount() { public int getItemCount() {
return dataSet.size() + 1; final int dataSetSize = dataSet.size();
return dataSetSize > 0 ? dataSetSize + 1 : 0;
} }
@Override @Override
@ -124,6 +129,11 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
} }
} }
@Override
public void setOnUpdatedListener(OnUpdatedListener listener) {
this.listener = listener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
final TextView songTitle; final TextView songTitle;
final TextView songInfo; final TextView songInfo;

View file

@ -0,0 +1,9 @@
package com.kabouzeid.gramophone.interfaces;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public interface OnUpdatedListener {
void onUpdated(SelfUpdating selfUpdating);
}

View file

@ -0,0 +1,9 @@
package com.kabouzeid.gramophone.interfaces;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public interface SelfUpdating {
void setOnUpdatedListener(OnUpdatedListener listener);
}

View file

@ -3,7 +3,6 @@ package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble; import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
import com.kabouzeid.gramophone.ui.activities.MainActivity; import com.kabouzeid.gramophone.ui.activities.MainActivity;
@ -13,14 +12,6 @@ import com.kabouzeid.gramophone.ui.activities.MainActivity;
public abstract class AbsMainActivityFragment extends Fragment implements KabViewsDisableAble { public abstract class AbsMainActivityFragment extends Fragment implements KabViewsDisableAble {
private boolean areViewsEnabled; private boolean areViewsEnabled;
protected int getTopPadding() {
return getResources().getDimensionPixelSize(R.dimen.list_padding_vertical);
}
protected int getBottomPadding() {
return getResources().getDimensionPixelSize(R.dimen.bottom_offset_fab_activity);
}
protected MainActivity getMainActivity() { protected MainActivity getMainActivity() {
return (MainActivity) getActivity(); return (MainActivity) getActivity();
} }

View file

@ -1,17 +1,23 @@
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments; package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.interfaces.OnUpdatedListener;
import com.kabouzeid.gramophone.interfaces.SelfUpdating;
import com.kabouzeid.gramophone.views.FastScroller;
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
public abstract class AbsMainActivityRecyclerViewFragment extends AbsMainActivityFragment { public abstract class AbsMainActivityRecyclerViewFragment extends AbsMainActivityFragment implements OnUpdatedListener {
public static final String TAG = AbsMainActivityRecyclerViewFragment.class.getSimpleName(); public static final String TAG = AbsMainActivityRecyclerViewFragment.class.getSimpleName();
private RecyclerView recyclerView; private RecyclerView recyclerView;
@ -19,20 +25,35 @@ public abstract class AbsMainActivityRecyclerViewFragment extends AbsMainActivit
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(getLayoutResId(), container, false); return inflater.inflate(R.layout.fragment_main_activity_recycler_view, container, false);
} }
@Override @Override
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
final FastScroller fastScroller = (FastScroller) view.findViewById(R.id.fast_scroller);
fastScroller.setRecyclerView(recyclerView);
fastScroller.setOnHandleTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
fastScroller.setPressedHandleColor(getMainActivity().getThemeColorPrimary());
setUpRecyclerView(); setUpRecyclerView();
checkAndProcessAdapterSize();
} }
private void setUpRecyclerView() { private void setUpRecyclerView() {
recyclerView.setLayoutManager(createLayoutManager());
recyclerView.setPadding(0, getTopPadding(), 0, getBottomPadding());
mAdapter = createAdapter(); mAdapter = createAdapter();
if (mAdapter instanceof SelfUpdating) ((SelfUpdating) mAdapter).setOnUpdatedListener(this);
recyclerView.setLayoutManager(createLayoutManager());
recyclerView.setAdapter(mAdapter); recyclerView.setAdapter(mAdapter);
} }
@ -52,9 +73,28 @@ public abstract class AbsMainActivityRecyclerViewFragment extends AbsMainActivit
recyclerView.setEnabled(false); recyclerView.setEnabled(false);
} }
protected abstract int getLayoutResId(); private void checkAndProcessAdapterSize() {
final View v = getView();
RecyclerView.Adapter adapter = getAdapter();
if (adapter != null && v != null) {
final TextView emptyTextView = (TextView) v.findViewById(android.R.id.empty);
emptyTextView.setText(getEmptyMessage());
emptyTextView.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
}
@StringRes
protected int getEmptyMessage() {
return R.string.nothing_here;
}
protected abstract RecyclerView.LayoutManager createLayoutManager(); protected abstract RecyclerView.LayoutManager createLayoutManager();
protected abstract RecyclerView.Adapter createAdapter(); protected abstract RecyclerView.Adapter createAdapter();
@Override
public void onUpdated(SelfUpdating selfUpdating) {
checkAndProcessAdapterSize();
}
} }

View file

@ -16,11 +16,6 @@ public class AlbumViewFragment extends AbsMainActivityRecyclerViewFragment {
private GridLayoutManager layoutManager; private GridLayoutManager layoutManager;
@Override
protected int getLayoutResId() {
return R.layout.fragment_album_view;
}
@Override @Override
protected RecyclerView.LayoutManager createLayoutManager() { protected RecyclerView.LayoutManager createLayoutManager() {
int columns = Util.isInPortraitMode(getActivity()) ? PreferenceUtils.getInstance(getActivity()).getAlbumGridColumns() : PreferenceUtils.getInstance(getActivity()).getAlbumGridColumnsLand(); int columns = Util.isInPortraitMode(getActivity()) ? PreferenceUtils.getInstance(getActivity()).getAlbumGridColumns() : PreferenceUtils.getInstance(getActivity()).getAlbumGridColumnsLand();
@ -33,6 +28,11 @@ public class AlbumViewFragment extends AbsMainActivityRecyclerViewFragment {
return new AlbumAdapter(getMainActivity(), getMainActivity()); return new AlbumAdapter(getMainActivity(), getMainActivity());
} }
@Override
protected int getEmptyMessage() {
return R.string.no_albums;
}
public void setColumns(int columns) { public void setColumns(int columns) {
layoutManager.setSpanCount(columns); layoutManager.setSpanCount(columns);
layoutManager.requestLayout(); layoutManager.requestLayout();

View file

@ -1,19 +1,17 @@
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments; package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.ArtistAdapter; import com.kabouzeid.gramophone.adapter.ArtistAdapter;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistViewFragment extends AbsMainActivityRecyclerViewFragment { public class ArtistViewFragment extends AbsMainActivityRecyclerViewFragment {
public static final String TAG = ArtistViewFragment.class.getSimpleName();
@Override public static final String TAG = ArtistViewFragment.class.getSimpleName();
protected int getLayoutResId() {
return R.layout.fragment_artist_view;
}
@Override @Override
protected RecyclerView.LayoutManager createLayoutManager() { protected RecyclerView.LayoutManager createLayoutManager() {
@ -24,4 +22,9 @@ public class ArtistViewFragment extends AbsMainActivityRecyclerViewFragment {
protected RecyclerView.Adapter createAdapter() { protected RecyclerView.Adapter createAdapter() {
return new ArtistAdapter(getMainActivity(), getMainActivity()); return new ArtistAdapter(getMainActivity(), getMainActivity());
} }
@Override
protected int getEmptyMessage() {
return R.string.no_artists;
}
} }

View file

@ -1,68 +1,30 @@
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments; package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R; import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.PlaylistAdapter; import com.kabouzeid.gramophone.adapter.PlaylistAdapter;
import com.kabouzeid.gramophone.model.DataBaseChangedEvent;
import com.squareup.otto.Subscribe;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class PlaylistViewFragment extends AbsMainActivityRecyclerViewFragment { public class PlaylistViewFragment extends AbsMainActivityRecyclerViewFragment {
public static final String TAG = PlaylistViewFragment.class.getSimpleName(); public static final String TAG = PlaylistViewFragment.class.getSimpleName();
@Override
protected int getLayoutResId() {
return R.layout.fragment_playlist_view;
}
@Override @Override
protected RecyclerView.LayoutManager createLayoutManager() { protected RecyclerView.LayoutManager createLayoutManager() {
return new GridLayoutManager(getActivity(), 1); return new GridLayoutManager(getActivity(), 1);
} }
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
App.bus.register(this);
}
@Override
public void onDestroy() {
super.onDestroy();
App.bus.unregister(this);
}
@Override @Override
protected RecyclerView.Adapter createAdapter() { protected RecyclerView.Adapter createAdapter() {
PlaylistAdapter adapter = new PlaylistAdapter(getMainActivity(), getMainActivity()); return new PlaylistAdapter(getMainActivity(), getMainActivity());
View v = getView();
if (v != null) {
v.findViewById(android.R.id.empty).setVisibility(
adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
return adapter;
} }
@Subscribe @Override
public void onDataBaseEvent(DataBaseChangedEvent event) { protected int getEmptyMessage() {
switch (event.getAction()) { return R.string.no_playlists;
case DataBaseChangedEvent.PLAYLISTS_CHANGED:
case DataBaseChangedEvent.DATABASE_CHANGED:
PlaylistAdapter adapter = (PlaylistAdapter) getAdapter();
adapter.loadDataSet();
adapter.notifyDataSetChanged();
View v = getView();
if (v != null) {
v.findViewById(android.R.id.empty).setVisibility(
adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
break;
}
} }
} }

View file

@ -13,11 +13,6 @@ public class SongViewFragment extends AbsMainActivityRecyclerViewFragment {
public static final String TAG = SongViewFragment.class.getSimpleName(); public static final String TAG = SongViewFragment.class.getSimpleName();
@Override
protected int getLayoutResId() {
return R.layout.fragment_songview;
}
@Override @Override
protected RecyclerView.LayoutManager createLayoutManager() { protected RecyclerView.LayoutManager createLayoutManager() {
return new GridLayoutManager(getActivity(), 1); return new GridLayoutManager(getActivity(), 1);
@ -27,4 +22,9 @@ public class SongViewFragment extends AbsMainActivityRecyclerViewFragment {
protected RecyclerView.Adapter createAdapter() { protected RecyclerView.Adapter createAdapter() {
return new SongAdapter(getMainActivity(), getMainActivity()); return new SongAdapter(getMainActivity(), getMainActivity());
} }
@Override
protected int getEmptyMessage() {
return R.string.no_songs;
}
} }

View file

@ -238,4 +238,12 @@ public class Util {
new int[]{color} new int[]{color}
); );
} }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static boolean isRTL(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration config = context.getResources().getConfiguration();
return config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
} else return false;
}
} }

View file

@ -0,0 +1,248 @@
package com.kabouzeid.gramophone.views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.StateListDrawable;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.util.Util;
/**
* Defines a basic widget that will allow for fast scrolling a RecyclerView using the basic paradigm of
* a handle and a bar.
*/
public class FastScroller extends FrameLayout {
/**
* The long bar along which a handle travels
*/
protected final View mBar;
/**
* The handle that signifies the user's progress in the list
*/
protected final View mHandle;
protected RecyclerView.OnScrollListener mOnScrollListener;
protected OnTouchListener mOnTouchListener;
private RecyclerView mRecyclerView;
private AnimatorSet mAnimator;
private boolean animatingIn;
private final Runnable mHide;
private final int mMinScrollHandleHeight;
private final int mHiddenTranslationX;
public FastScroller(Context context) {
this(context, null, 0);
}
public FastScroller(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FastScroller(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context, R.layout.vertical_recycler_fast_scroller_layout, this);
mBar = findViewById(R.id.scroll_bar);
mHandle = findViewById(R.id.scroll_handle);
mMinScrollHandleHeight = getResources().getDimensionPixelSize(R.dimen.min_scrollhandle_height);
mHiddenTranslationX = (Util.isRTL(getContext()) ? -1 : 1) * getResources().getDimensionPixelSize(R.dimen.scrollbar_width);
mHide = new Runnable() {
@Override
public void run() {
if (!mHandle.isPressed()) {
if (mAnimator != null && mAnimator.isStarted()) {
mAnimator.cancel();
}
mAnimator = new AnimatorSet();
ObjectAnimator animator2 = ObjectAnimator.ofFloat(FastScroller.this, View.TRANSLATION_X,
mHiddenTranslationX);
animator2.setInterpolator(new FastOutLinearInInterpolator());
animator2.setDuration(150);
mHandle.setEnabled(false);
mAnimator.play(animator2);
mAnimator.start();
}
}
};
mHandle.setOnTouchListener(new OnTouchListener() {
private float mInitialBarHeight;
private float mLastPressedYAdjustedToInitial;
@Override
public boolean onTouch(View v, MotionEvent event) {
mOnTouchListener.onTouch(v, event);
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
mHandle.setPressed(true);
mInitialBarHeight = mBar.getHeight();
mLastPressedYAdjustedToInitial = event.getY() + mHandle.getY() + mBar.getY();
} else if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
float newHandlePressedY = event.getY() + mHandle.getY() + mBar.getY();
int barHeight = mBar.getHeight();
float newHandlePressedYAdjustedToInitial =
newHandlePressedY + (mInitialBarHeight - barHeight);
float deltaPressedYFromLastAdjustedToInitial =
newHandlePressedYAdjustedToInitial - mLastPressedYAdjustedToInitial;
int dY = (int) ((deltaPressedYFromLastAdjustedToInitial / mInitialBarHeight) *
(mRecyclerView.computeVerticalScrollRange()));
updateRvScroll(dY);
mLastPressedYAdjustedToInitial = newHandlePressedYAdjustedToInitial;
} else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
mLastPressedYAdjustedToInitial = -1;
mHandle.setPressed(false);
postAutoHide();
}
return true;
}
});
setTranslationX(mHiddenTranslationX);
//Default selected handle color
setPressedHandleColor(Color.BLACK);
setUpBarBackground();
}
/**
* Provides the ability to programmatically set the color of the fast scroller's handle
*/
public void setPressedHandleColor(int accent) {
StateListDrawable drawable = new StateListDrawable();
int colorControlNormal = Util.resolveColor(getContext(), R.attr.colorControlNormal);
if (!Util.isRTL(getContext())) {
drawable.addState(View.PRESSED_ENABLED_STATE_SET,
new InsetDrawable(new ColorDrawable(accent), getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0, 0));
drawable.addState(View.EMPTY_STATE_SET,
new InsetDrawable(new ColorDrawable(colorControlNormal), getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0, 0));
} else {
drawable.addState(View.PRESSED_ENABLED_STATE_SET,
new InsetDrawable(new ColorDrawable(accent), 0, getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0));
drawable.addState(View.EMPTY_STATE_SET,
new InsetDrawable(new ColorDrawable(colorControlNormal), 0, getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0));
}
mHandle.setBackground(drawable);
}
private void setUpBarBackground() {
Drawable drawable;
int colorControlNormal = Util.resolveColor(getContext(), R.attr.colorControlNormal);
if (!Util.isRTL(getContext())) {
drawable = new InsetDrawable(new ColorDrawable(colorControlNormal), getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0, 0);
} else {
drawable = new InsetDrawable(new ColorDrawable(colorControlNormal), 0, getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0);
}
mBar.setBackground(drawable);
}
public void setRecyclerView(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
initRecyclerViewOnScrollListener();
}
public void initRecyclerViewOnScrollListener() {
mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
requestLayout();
mHandle.setEnabled(true);
if (!animatingIn && getTranslationX() != 0) {
if (mAnimator != null && mAnimator.isStarted()) {
mAnimator.cancel();
}
mAnimator = new AnimatorSet();
ObjectAnimator animator = ObjectAnimator.ofFloat(FastScroller.this, View.TRANSLATION_X, 0);
animator.setInterpolator(new LinearOutSlowInInterpolator());
animator.setDuration(100);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animatingIn = false;
}
});
animatingIn = true;
mAnimator.play(animator);
mAnimator.start();
}
postAutoHide();
}
};
mRecyclerView.addOnScrollListener(mOnScrollListener);
}
public void setOnHandleTouchListener(OnTouchListener listener) {
mOnTouchListener = listener;
}
private void postAutoHide() {
if (mRecyclerView != null) {
mRecyclerView.removeCallbacks(mHide);
mRecyclerView.postDelayed(mHide, 1500);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int scrollOffset = mRecyclerView.computeVerticalScrollOffset();
int verticalScrollRange = mRecyclerView.computeVerticalScrollRange()
+ mRecyclerView.getPaddingBottom();
int barHeight = mBar.getHeight();
float ratio = (float) scrollOffset / (verticalScrollRange - barHeight);
int calculatedHandleHeight = (int) ((float) barHeight / verticalScrollRange * barHeight);
if (calculatedHandleHeight < mMinScrollHandleHeight) {
calculatedHandleHeight = mMinScrollHandleHeight;
}
if (calculatedHandleHeight >= barHeight) {
setTranslationX(mHiddenTranslationX);
return;
}
float y = ratio * (barHeight - calculatedHandleHeight);
mHandle.layout(mHandle.getLeft(), (int) y, mHandle.getRight(), (int) y + calculatedHandleHeight);
}
public void updateRvScroll(int dY) {
if (mRecyclerView != null && mHandle != null) {
try {
mRecyclerView.scrollBy(0, dY);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}

View file

@ -1,12 +1,12 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<FrameLayout <FrameLayout
android:background="?android:colorBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/header_image_height"> android:layout_height="@dimen/header_image_height"
android:background="?android:colorBackground">
<ImageView <ImageView
android:id="@+id/album_art_background" android:id="@+id/album_art_background"
@ -98,6 +98,6 @@
android:id="@+id/fab" android:id="@+id/fab"
style="@style/PlayPauseFab" style="@style/PlayPauseFab"
android:layout_gravity="end|right|bottom" android:layout_gravity="end|right|bottom"
android:layout_margin="16dp" /> android:layout_margin="@dimen/fab_margin" />
</FrameLayout> </FrameLayout>

View file

@ -1,10 +1,10 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true"> android:focusableInTouchMode="true">
<com.github.ksoichiro.android.observablescrollview.ObservableScrollView <com.github.ksoichiro.android.observablescrollview.ObservableScrollView
android:id="@+id/observableScrollView" android:id="@+id/observableScrollView"
@ -26,6 +26,7 @@
android:id="@+id/header" android:id="@+id/header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/image"
android:elevation="@dimen/toolbar_elevation" android:elevation="@dimen/toolbar_elevation"
android:minHeight="@dimen/title_view_height" android:minHeight="@dimen/title_view_height"
android:orientation="vertical" android:orientation="vertical"
@ -33,8 +34,7 @@
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="16dp" android:paddingRight="16dp"
android:paddingTop="8dp" android:paddingTop="8dp"
tools:ignore="UnusedAttribute" tools:ignore="UnusedAttribute">
android:layout_below="@+id/image">
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -139,7 +139,7 @@
android:id="@+id/fab" android:id="@+id/fab"
style="@style/PlayPauseFab" style="@style/PlayPauseFab"
android:layout_gravity="bottom|right|end" android:layout_gravity="bottom|right|end"
android:layout_margin="16dp" android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_done_white_24dp" android:src="@drawable/ic_done_white_24dp"
tools:ignore="RtlHardcoded" /> tools:ignore="RtlHardcoded" />

View file

@ -1,13 +1,13 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<FrameLayout <FrameLayout
android:background="?android:colorBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/header_image_height"> android:layout_height="@dimen/header_image_height"
android:background="?android:colorBackground">
<ImageView <ImageView
android:id="@+id/artist_image_background" android:id="@+id/artist_image_background"
@ -99,6 +99,6 @@
android:id="@+id/fab" android:id="@+id/fab"
style="@style/PlayPauseFab" style="@style/PlayPauseFab"
android:layout_gravity="end|right|bottom" android:layout_gravity="end|right|bottom"
android:layout_margin="16dp" /> android:layout_margin="@dimen/fab_margin" />
</FrameLayout> </FrameLayout>

View file

@ -1,8 +1,8 @@
<android.support.v4.widget.DrawerLayout <android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
@ -19,9 +19,9 @@
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<FrameLayout <FrameLayout
app:layout_scrollFlags="scroll|enterAlways"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
<android.support.v7.widget.Toolbar <android.support.v7.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
@ -59,7 +59,7 @@
android:id="@+id/fab" android:id="@+id/fab"
style="@style/PlayPauseFab" style="@style/PlayPauseFab"
android:layout_gravity="end|bottom" android:layout_gravity="end|bottom"
android:layout_margin="16dp" /> android:layout_margin="@dimen/fab_margin" />
</android.support.design.widget.CoordinatorLayout> </android.support.design.widget.CoordinatorLayout>

View file

@ -1,18 +1,18 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="com.kabouzeid.gramophone.ui.activities.MusicControllerActivity"> tools:context="com.kabouzeid.gramophone.ui.activities.MusicControllerActivity">
<!-- BOTTOM--> <!-- BOTTOM-->
<LinearLayout <LinearLayout
android:background="?android:colorBackground"
android:id="@+id/footer_frame" android:id="@+id/footer_frame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:background="?android:colorBackground"
android:orientation="vertical"> android:orientation="vertical">
<RelativeLayout <RelativeLayout
@ -166,7 +166,8 @@
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
style="@style/PlayPauseFab" style="@style/PlayPauseFab"
android:layout_centerInParent="true" /> android:layout_centerInParent="true"
android:layout_margin="@dimen/tmp_no_fab_margin" />
</RelativeLayout> </RelativeLayout>

View file

@ -1,6 +1,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,6 +49,6 @@
android:id="@+id/fab" android:id="@+id/fab"
style="@style/PlayPauseFab" style="@style/PlayPauseFab"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_margin="16dp" /> android:layout_margin="@dimen/fab_margin" />
</FrameLayout> </FrameLayout>

View file

@ -1,10 +1,10 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true"> android:focusableInTouchMode="true">
<com.github.ksoichiro.android.observablescrollview.ObservableScrollView <com.github.ksoichiro.android.observablescrollview.ObservableScrollView
android:id="@+id/observableScrollView" android:id="@+id/observableScrollView"
@ -85,8 +85,7 @@
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
>
<EditText <EditText
android:id="@+id/artist" android:id="@+id/artist"
@ -105,8 +104,7 @@
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
>
<EditText <EditText
android:id="@+id/genre" android:id="@+id/genre"
@ -125,8 +123,7 @@
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
>
<EditText <EditText
android:id="@+id/year" android:id="@+id/year"
@ -146,8 +143,7 @@
<android.support.design.widget.TextInputLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
>
<EditText <EditText
android:id="@+id/track_number" android:id="@+id/track_number"
@ -181,7 +177,7 @@
android:id="@+id/fab" android:id="@+id/fab"
style="@style/PlayPauseFab" style="@style/PlayPauseFab"
android:layout_gravity="bottom|right|end" android:layout_gravity="bottom|right|end"
android:layout_margin="16dp" android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_done_white_24dp" android:src="@drawable/ic_done_white_24dp"
tools:ignore="RtlHardcoded" /> tools:ignore="RtlHardcoded" />

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/fragment_album_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical" />
</LinearLayout>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/fragment_album_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical" />
</LinearLayout>

View file

@ -1,18 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_song_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView <android.support.v7.widget.RecyclerView
android:paddingTop="@dimen/list_padding_vertical"
android:paddingBottom="@dimen/bottom_offset_fab_activity"
android:id="@+id/recycler_view" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:dividerHeight="0px" android:scrollbars="none" />
android:divider="@null"
android:scrollbars="vertical" />
<TextView <TextView
android:id="@android:id/empty" android:id="@android:id/empty"
@ -21,7 +19,13 @@
android:textSize="@dimen/empty_text_size" android:textSize="@dimen/empty_text_size"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorSecondary"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:text="@string/no_playlists" android:text="@string/nothing_here"
android:layout_gravity="center" /> android:layout_gravity="center" />
<com.kabouzeid.gramophone.views.FastScroller
android:id="@+id/fast_scroller"
android:layout_gravity="end"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/fragment_song_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:listSelector="?rect_selector"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:dividerHeight="0px"
android:divider="@null"
android:scrollbars="vertical" />
</LinearLayout>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="48dp"
android:layout_height="match_parent"
tools:layout_gravity="end">
<View
android:id="@+id/scroll_bar"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:alpha="0.22352941176" />
<View
android:id="@+id/scroll_handle"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="end" />
</FrameLayout>

View file

@ -2,4 +2,7 @@
<resources> <resources>
<dimen name="status_bar_padding">25dp</dimen> <dimen name="status_bar_padding">25dp</dimen>
<dimen name="navigation_drawer_header_height">165dp</dimen> <dimen name="navigation_drawer_header_height">165dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="tmp_no_fab_margin">0dp</dimen>
</resources> </resources>

View file

@ -50,4 +50,12 @@ http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
<dimen name="notification_albumart_size">128dp</dimen> <dimen name="notification_albumart_size">128dp</dimen>
<dimen name="bottom_offset_fab_activity">86dp</dimen> <dimen name="bottom_offset_fab_activity">86dp</dimen>
<dimen name="min_scrollhandle_height">48dp</dimen>
<dimen name="scrollbar_width">8dp</dimen>
<dimen name="scrollbar_inset">40dp</dimen>
<!-- ONLY 0dp WHILE THERE IS THE BUG IN DESIGN SUPPORT LIBRARY 22.2.0-->
<dimen name="fab_margin">0dp</dimen>
<dimen name="tmp_no_fab_margin">-16dp</dimen>
</resources> </resources>

View file

@ -140,6 +140,10 @@
<string name="update_image">Update Image</string> <string name="update_image">Update Image</string>
<string name="playlist_empty_text">This playlist is empty</string> <string name="playlist_empty_text">This playlist is empty</string>
<string name="no_playlists">No playlists</string> <string name="no_playlists">No playlists</string>
<string name="no_albums">No albums</string>
<string name="no_songs">No songs</string>
<string name="no_artists">No artists</string>
<string name="nothing_here">Nothing here</string>
<string name="playlist_name">Playlist name</string> <string name="playlist_name">Playlist name</string>
<string name="song">Song</string> <string name="song">Song</string>
<string name="pref_only_lollipop">Only available on Lollipop.</string> <string name="pref_only_lollipop">Only available on Lollipop.</string>